From 968a34ffdaadd7db062a9621dfbdf8b2d16e05af Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 20 Dec 2018 12:29:59 -0800 Subject: Export of internal Abseil changes. -- 7fa1107161a03dac53fb84c2b06d8092616c7b13 by Abseil Team : Harden the generic stacktrace implementation for use during early program execution PiperOrigin-RevId: 226375950 -- 079f9969329f5eb66f647dd3c44b17541b1bf217 by Matt Kulukundis : Workaround platforms that have over-aggressive warnings on -Wexit-time-destructors PiperOrigin-RevId: 226362948 -- 1447943f509be681ca5495add0162c750ef237f1 by Matt Kulukundis : Switch from 64 to size_t atomics so they work on embedded platforms that do not have 64 bit atomics. PiperOrigin-RevId: 226210704 -- d14d49837ae2bcde74051e0c79c18ee0f43866b9 by Tom Manshreck : Develop initial documentation for API breaking changes process: PiperOrigin-RevId: 226210021 -- 7ea3d7fe0e86979dab83a5fc9cc3bf1d6cb3bd53 by Abseil Team : Import of CCTZ from GitHub. PiperOrigin-RevId: 226195522 -- 7de873e880d7f016a4fa1e08d626f0535cc470af by Abseil Team : Make Abseil LICENSE files newline terminated, with a single trailing blank line. Also remove line-ending whitespace. PiperOrigin-RevId: 226182949 -- 7d00643fadfad7f0d992c68bd9d2ed2e5bc960b0 by Matt Kulukundis : Internal cleanup PiperOrigin-RevId: 226045282 -- c4a0a11c0ce2875271191e477f3d36eaaeca4613 by Matt Kulukundis : Internal cleanup PiperOrigin-RevId: 226038273 -- 8ee4ebbb1ae5cda119e436e5ff7e3aa966608c10 by Matt Kulukundis : Adds a global sampler which tracks a fraction of live tables for collecting telemetry data. PiperOrigin-RevId: 226032080 -- d576446f050518cd1b0ae447d682d8552f0e7e30 by Mark Barolak : Replace an internal CaseEqual function with calls to the identical absl::EqualsIgnoreCase. This closes out a rather old TODO. PiperOrigin-RevId: 226024779 -- 6b23f1ee028a5ffa608c920424f1220a117a8f3d by Abseil Team : Add December 2018 LTS branch to list of LTS branches. PiperOrigin-RevId: 226011333 -- bb0833a43bdaef4c8c059b17bcd27ba9a085a114 by Mark Barolak : Explicitly state that when the SimpleAtoi family of functions encounter an error, the value of their output parameter is unspecified. Also standardize the name of the output parameter to be `out`. PiperOrigin-RevId: 225997035 -- 46c1876b1a248eabda7545daa61a74a4cdfe9077 by Abseil Team : Remove deprecated CMake function absl_test, absl_library and absl_header_library PiperOrigin-RevId: 225950041 GitOrigin-RevId: 7fa1107161a03dac53fb84c2b06d8092616c7b13 Change-Id: I2ca9d3aada9292614527d1339a7557494139b806 --- absl/container/internal/hashtablez_sampler.cc | 289 ++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 absl/container/internal/hashtablez_sampler.cc (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc new file mode 100644 index 00000000..6cc10c20 --- /dev/null +++ b/absl/container/internal/hashtablez_sampler.cc @@ -0,0 +1,289 @@ +// 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 +// +// http://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/container/internal/hashtablez_sampler.h" + +#include +#include +#include +#include + +#include "absl/base/attributes.h" +#include "absl/container/internal/have_sse.h" +#include "absl/debugging/stacktrace.h" +#include "absl/memory/memory.h" +#include "absl/synchronization/mutex.h" + +namespace absl { +namespace container_internal { +constexpr int HashtablezInfo::kMaxStackDepth; + +namespace { +ABSL_CONST_INIT std::atomic g_hashtablez_enabled{ + false +}; +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 = (std::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); +} + +} // namespace + +HashtablezSampler& HashtablezSampler::Global() { + static auto* sampler = new HashtablezSampler(); + return *sampler; +} + +HashtablezInfo::HashtablezInfo() { PrepareForSampling(); } +HashtablezInfo::~HashtablezInfo() = default; + +void HashtablezInfo::PrepareForSampling() { + capacity.store(0, std::memory_order_relaxed); + size.store(0, std::memory_order_relaxed); + num_erases.store(0, std::memory_order_relaxed); + max_probe_length.store(0, std::memory_order_relaxed); + total_probe_length.store(0, std::memory_order_relaxed); + hashes_bitwise_or.store(0, std::memory_order_relaxed); + hashes_bitwise_and.store(~size_t{}, std::memory_order_relaxed); + + create_time = absl::Now(); + // The inliner makes hardcoded skip_count difficult (especially when combined + // with LTO). We use the ability to exclude stacks by regex when encoding + // instead. + depth = absl::GetStackTrace(stack, HashtablezInfo::kMaxStackDepth, + /* skip_count= */ 0); + dead = nullptr; +} + +HashtablezSampler::HashtablezSampler() + : dropped_samples_(0), size_estimate_(0), all_(nullptr) { + absl::MutexLock l(&graveyard_.init_mu); + graveyard_.dead = &graveyard_; +} + +HashtablezSampler::~HashtablezSampler() { + HashtablezInfo* s = all_.load(std::memory_order_acquire); + while (s != nullptr) { + HashtablezInfo* next = s->next; + delete s; + s = next; + } +} + +void HashtablezSampler::PushNew(HashtablezInfo* sample) { + sample->next = all_.load(std::memory_order_relaxed); + while (!all_.compare_exchange_weak(sample->next, sample, + std::memory_order_release, + std::memory_order_relaxed)) { + } +} + +void HashtablezSampler::PushDead(HashtablezInfo* sample) { + absl::MutexLock graveyard_lock(&graveyard_.init_mu); + absl::MutexLock sample_lock(&sample->init_mu); + sample->dead = graveyard_.dead; + graveyard_.dead = sample; +} + +HashtablezInfo* HashtablezSampler::PopDead() { + absl::MutexLock graveyard_lock(&graveyard_.init_mu); + + // The list is circular, so eventually it collapses down to + // graveyard_.dead == &graveyard_ + // when it is empty. + HashtablezInfo* sample = graveyard_.dead; + if (sample == &graveyard_) return nullptr; + + absl::MutexLock sample_lock(&sample->init_mu); + graveyard_.dead = sample->dead; + sample->PrepareForSampling(); + return sample; +} + +HashtablezInfo* HashtablezSampler::Register() { + int64_t size = size_estimate_.fetch_add(1, std::memory_order_relaxed); + if (size > g_hashtablez_max_samples.load(std::memory_order_relaxed)) { + size_estimate_.fetch_sub(1, std::memory_order_relaxed); + dropped_samples_.fetch_add(1, std::memory_order_relaxed); + return nullptr; + } + + HashtablezInfo* sample = PopDead(); + if (sample == nullptr) { + // Resurrection failed. Hire a new warlock. + sample = new HashtablezInfo(); + PushNew(sample); + } + + return sample; +} + +void HashtablezSampler::Unregister(HashtablezInfo* sample) { + PushDead(sample); + size_estimate_.fetch_sub(1, std::memory_order_relaxed); +} + +int64_t HashtablezSampler::Iterate( + const std::function& f) { + HashtablezInfo* s = all_.load(std::memory_order_acquire); + while (s != nullptr) { + absl::MutexLock l(&s->init_mu); + if (s->dead == nullptr) { + f(*s); + } + s = s->next; + } + + return dropped_samples_.load(std::memory_order_relaxed); +} + +HashtablezInfo* SampleSlow(int64_t* next_sample) { + bool first = *next_sample < 0; + *next_sample = GetGeometricVariable( + g_hashtablez_sample_parameter.load(std::memory_order_relaxed)); + + // 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 + // the default sampling rate. + if (!g_hashtablez_enabled.load(std::memory_order_relaxed)) return nullptr; + + // We will only be negative on our first count, so we should just retry in + // that case. + if (first) { + if (ABSL_PREDICT_TRUE(--*next_sample > 0)) return nullptr; + return SampleSlow(next_sample); + } + + return HashtablezSampler::Global().Register(); +} + +void UnsampleSlow(HashtablezInfo* info) { + HashtablezSampler::Global().Unregister(info); +} + +void RecordInsertSlow(HashtablezInfo* info, size_t hash, + size_t distance_from_desired) { + // SwissTables probe in groups of 16, so scale this to count items probes and + // not offset from desired. + size_t probe_length = distance_from_desired; +#if SWISSTABLE_HAVE_SSE2 + probe_length /= 16; +#else + probe_length /= 8; +#endif + + info->hashes_bitwise_and.fetch_and(hash, std::memory_order_relaxed); + info->hashes_bitwise_or.fetch_or(hash, std::memory_order_relaxed); + info->max_probe_length.store( + std::max(info->max_probe_length.load(std::memory_order_relaxed), + probe_length), + std::memory_order_relaxed); + info->total_probe_length.fetch_add(probe_length, std::memory_order_relaxed); + info->size.fetch_add(1, std::memory_order_relaxed); +} + +void SetHashtablezEnabled(bool enabled) { + g_hashtablez_enabled.store(enabled, std::memory_order_release); +} + +void SetHashtablezSampleParameter(int32_t rate) { + if (rate > 0) { + g_hashtablez_sample_parameter.store(rate, std::memory_order_release); + } else { + ABSL_RAW_LOG(ERROR, "Invalid hashtablez sample rate: %lld", + static_cast(rate)); // NOLINT(runtime/int) + } +} + +void SetHashtablezMaxSamples(int32_t max) { + if (max > 0) { + g_hashtablez_max_samples.store(max, std::memory_order_release); + } else { + ABSL_RAW_LOG(ERROR, "Invalid hashtablez max samples: %lld", + static_cast(max)); // NOLINT(runtime/int) + } +} + +} // namespace container_internal +} // namespace absl -- cgit v1.2.3 From b16aeb6756bdab08cdf12d40baab5b51f7d15b16 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 7 Jan 2019 09:01:16 -0800 Subject: Export of internal Abseil changes. -- 5f1cf6547231f1b1daad6d1b785df6b0b999b3c9 by Samuel Benzaquen : Fix uninitialized member in the `iterator` class by using a union of the two possible states of the iterator. This silences a Wuninitialized warning in gcc>=7. PiperOrigin-RevId: 228175148 -- 98b4e3204c0ec3cfd4cb037e24d443ea4b63fc84 by CJ Johnson : Factors out the implementation of InlinedVector::swap(...) into a private member function PiperOrigin-RevId: 228173383 -- f1432ad3a8b05285c6d55bc4754cfae765485b7f by Abseil Team : Import of CCTZ from GitHub. PiperOrigin-RevId: 227891984 -- 03fc00c7a4efc6000e6d9125cb2e252bffda76fe by Andy Getzendanner : Add a missing linebreak to a comment and markdownify two unordered lists. PiperOrigin-RevId: 227861389 -- 0d66c9afba4fc9aa52e61d9fb410e165018a7b48 by Abseil Team : Add an API to register a new source for the cycle clock. PiperOrigin-RevId: 227779218 -- 14d3f9b70c8818b8541e5fb2f6ca4c59d479de31 by Andy Getzendanner : Correct a typo in a stripping marker. PiperOrigin-RevId: 227750014 -- 59df88740f4e315beb57a8772f8bcf7879440c74 by Matt Kulukundis : Switch thread local handling to be more cross platform PiperOrigin-RevId: 227695133 -- 75deed5bfcb5c42534e933f104aa7d94e11e348d by Abseil Team : Rollback workaround toolchain bug for incorrect handling of thread_local in inline functions PiperOrigin-RevId: 227689133 -- 54994bf0afec026e6e0e7a199df0bbb4b7d9a4aa by Derek Mauro : Add -pthread to linkopts where it actually belongs, on the library that uses it. Fixes https://github.com/abseil/abseil-cpp/issues/240. PiperOrigin-RevId: 227612492 -- 893875f3536b7e0a1bad993aa6b2e083abb3b25a by Derek Mauro : Internal change PiperOrigin-RevId: 227582833 -- 506c9b8e9002ca3389c7040473b68d4cbf94bdcc by Matt Kulukundis : Workaround toolchain bug for incorrect handling of thread_local in inline functions PiperOrigin-RevId: 227561449 -- 29ee90d96dfe3114cf93f9bb92ea0cc9e768a407 by Derek Mauro : Internal change PiperOrigin-RevId: 227054634 GitOrigin-RevId: 5f1cf6547231f1b1daad6d1b785df6b0b999b3c9 Change-Id: Ibc90566d92ee6e0ad7e150f513ec7f5d22ec0a94 --- UPGRADES.md | 17 +++ absl/UPGRADES.md | 17 --- absl/base/BUILD.bazel | 16 +-- absl/base/internal/cycleclock.cc | 12 +- absl/base/internal/cycleclock.h | 14 ++ absl/base/internal/per_thread_tls.h | 12 +- absl/container/BUILD.bazel | 11 ++ absl/container/CMakeLists.txt | 11 ++ absl/container/inlined_vector.h | 151 +++++++++++---------- absl/container/inlined_vector_test.cc | 53 +------- absl/container/internal/counting_allocator.h | 79 +++++++++++ absl/container/internal/hashtablez_sampler.cc | 4 + absl/container/internal/hashtablez_sampler.h | 11 +- absl/container/internal/raw_hash_set.h | 6 +- absl/copts/copts.py | 2 - absl/synchronization/BUILD.bazel | 8 +- absl/time/internal/cctz/BUILD.bazel | 2 +- .../internal/cctz/src/time_zone_format_test.cc | 17 +-- .../internal/cctz/src/time_zone_lookup_test.cc | 2 + absl/time/internal/cctz/testdata/version | 2 +- .../cctz/testdata/zoneinfo/Africa/Sao_Tome | Bin 225 -> 254 bytes .../cctz/testdata/zoneinfo/America/Metlakatla | Bin 1409 -> 1409 bytes .../internal/cctz/testdata/zoneinfo/Asia/Hong_Kong | Bin 1175 -> 1191 bytes .../internal/cctz/testdata/zoneinfo/Asia/Qostanay | Bin 0 -> 1033 bytes .../internal/cctz/testdata/zoneinfo/Asia/Qyzylorda | Bin 1017 -> 1047 bytes .../internal/cctz/testdata/zoneinfo/Asia/Tehran | Bin 1704 -> 2610 bytes absl/time/internal/cctz/testdata/zoneinfo/Hongkong | Bin 1175 -> 1191 bytes absl/time/internal/cctz/testdata/zoneinfo/Iran | Bin 1704 -> 2610 bytes .../time/internal/cctz/testdata/zoneinfo/Kwajalein | Bin 250 -> 340 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Chuuk | Bin 174 -> 287 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Guam | Bin 216 -> 516 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Kosrae | Bin 242 -> 377 bytes .../cctz/testdata/zoneinfo/Pacific/Kwajalein | Bin 250 -> 340 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Majuro | Bin 212 -> 330 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Nauru | Bin 268 -> 268 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Palau | Bin 173 -> 190 bytes .../cctz/testdata/zoneinfo/Pacific/Pohnpei | Bin 174 -> 325 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Ponape | Bin 174 -> 325 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Saipan | Bin 216 -> 516 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Truk | Bin 174 -> 287 bytes .../internal/cctz/testdata/zoneinfo/Pacific/Yap | Bin 174 -> 287 bytes .../internal/cctz/testdata/zoneinfo/zone1970.tab | 1 + 42 files changed, 270 insertions(+), 178 deletions(-) create mode 100644 UPGRADES.md delete mode 100644 absl/UPGRADES.md create mode 100644 absl/container/internal/counting_allocator.h create mode 100644 absl/time/internal/cctz/testdata/zoneinfo/Asia/Qostanay (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/UPGRADES.md b/UPGRADES.md new file mode 100644 index 00000000..edbc4dc4 --- /dev/null +++ b/UPGRADES.md @@ -0,0 +1,17 @@ +# C++ Upgrade Tools + +Abseil may occassionally release API-breaking changes. As noted in our +[Compatibility Guidelines][compatibility-guide], we will aim to provide a tool +to do the work of effecting such API-breaking changes, when absolutely +necessary. + +These tools will be listed on the [C++ Upgrade Tools][upgrade-tools] guide on +http://abseil.io. + +For more information, the [C++ Automated Upgrade Guide][api-upgrades-guide] +outlines this process. + +[compatibility-guide]: https://abseil.io/about/compatibility +[api-upgrades-guide]: https://abseil.io/docs/cpp/tools/api-upgrades +[upgrade-tools]: https://abseil.io/docs/cpp/tools/upgrades/ + diff --git a/absl/UPGRADES.md b/absl/UPGRADES.md deleted file mode 100644 index edbc4dc4..00000000 --- a/absl/UPGRADES.md +++ /dev/null @@ -1,17 +0,0 @@ -# C++ Upgrade Tools - -Abseil may occassionally release API-breaking changes. As noted in our -[Compatibility Guidelines][compatibility-guide], we will aim to provide a tool -to do the work of effecting such API-breaking changes, when absolutely -necessary. - -These tools will be listed on the [C++ Upgrade Tools][upgrade-tools] guide on -http://abseil.io. - -For more information, the [C++ Automated Upgrade Guide][api-upgrades-guide] -outlines this process. - -[compatibility-guide]: https://abseil.io/about/compatibility -[api-upgrades-guide]: https://abseil.io/docs/cpp/tools/api-upgrades -[upgrade-tools]: https://abseil.io/docs/cpp/tools/upgrades/ - diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 2717df0c..49ae1824 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -89,6 +89,10 @@ cc_library( "internal/low_level_alloc.h", ], copts = ABSL_DEFAULT_COPTS, + linkopts = select({ + "//absl:windows": [], + "//conditions:default": ["-pthread"], + }), visibility = [ "//absl:__subpackages__", ], @@ -142,6 +146,10 @@ cc_library( "log_severity.h", ], copts = ABSL_DEFAULT_COPTS, + linkopts = select({ + "//absl:windows": [], + "//conditions:default": ["-pthread"], + }), deps = [ ":base_internal", ":config", @@ -423,10 +431,6 @@ cc_test( size = "small", srcs = ["internal/low_level_alloc_test.cc"], copts = ABSL_TEST_COPTS, - linkopts = select({ - "//absl:windows": [], - "//conditions:default": ["-pthread"], - }), tags = ["no_test_ios_x86_64"], deps = [":malloc_internal"], ) @@ -436,10 +440,6 @@ cc_test( size = "small", srcs = ["internal/thread_identity_test.cc"], copts = ABSL_TEST_COPTS, - linkopts = select({ - "//absl:windows": [], - "//conditions:default": ["-pthread"], - }), tags = [ "no_test_wasm", ], diff --git a/absl/base/internal/cycleclock.cc b/absl/base/internal/cycleclock.cc index a742df01..9eb13b8c 100644 --- a/absl/base/internal/cycleclock.cc +++ b/absl/base/internal/cycleclock.cc @@ -22,6 +22,7 @@ #include "absl/base/internal/cycleclock.h" +#include #include // NOLINT(build/c++11) #include "absl/base/internal/unscaledcycleclock.h" @@ -52,17 +53,26 @@ static constexpr int32_t kShift = 2; #endif static constexpr double kFrequencyScale = 1.0 / (1 << kShift); +static std::atomic cycle_clock_source; } // namespace int64_t CycleClock::Now() { - return base_internal::UnscaledCycleClock::Now() >> kShift; + auto fn = cycle_clock_source.load(std::memory_order_relaxed); + if (fn == nullptr) { + return base_internal::UnscaledCycleClock::Now() >> kShift; + } + return fn() >> kShift; } double CycleClock::Frequency() { return kFrequencyScale * base_internal::UnscaledCycleClock::Frequency(); } +void CycleClockSource::Register(CycleClockSourceFunc source) { + cycle_clock_source.store(source, std::memory_order_relaxed); +} + #else int64_t CycleClock::Now() { diff --git a/absl/base/internal/cycleclock.h b/absl/base/internal/cycleclock.h index 60e97158..9853a66c 100644 --- a/absl/base/internal/cycleclock.h +++ b/absl/base/internal/cycleclock.h @@ -71,6 +71,20 @@ class CycleClock { CycleClock& operator=(const CycleClock&) = delete; }; +using CycleClockSourceFunc = int64_t (*)(); + +class CycleClockSource { + private: + // CycleClockSource::Register() + // + // Register a function that provides an alternate source for the unscaled CPU + // cycle count value. The source function must be async signal safe, must not + // call CycleClock::Now(), and must have a frequency that matches that of the + // unscaled clock used by CycleClock. A nullptr value resets CycleClock to use + // the default source. + static void Register(CycleClockSourceFunc source); +}; + } // namespace base_internal } // namespace absl diff --git a/absl/base/internal/per_thread_tls.h b/absl/base/internal/per_thread_tls.h index 2428bdc1..56359853 100644 --- a/absl/base/internal/per_thread_tls.h +++ b/absl/base/internal/per_thread_tls.h @@ -16,13 +16,17 @@ #define ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ // This header defines two macros: +// // If the platform supports thread-local storage: -// ABSL_PER_THREAD_TLS_KEYWORD is the C keyword needed to declare a -// thread-local variable ABSL_PER_THREAD_TLS is 1 +// +// * ABSL_PER_THREAD_TLS_KEYWORD is the C keyword needed to declare a +// thread-local variable +// * ABSL_PER_THREAD_TLS is 1 // // Otherwise: -// ABSL_PER_THREAD_TLS_KEYWORD is empty -// ABSL_PER_THREAD_TLS is 0 +// +// * ABSL_PER_THREAD_TLS_KEYWORD is empty +// * ABSL_PER_THREAD_TLS is 0 // // Microsoft C supports thread-local storage. // GCC supports it if the appropriate version of glibc is available, diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index e1880a8b..623faf45 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -123,12 +123,21 @@ cc_library( ], ) +cc_library( + name = "counting_allocator", + testonly = 1, + hdrs = ["internal/counting_allocator.h"], + copts = ABSL_DEFAULT_COPTS, + visibility = ["//visibility:private"], +) + cc_test( name = "inlined_vector_test", srcs = ["inlined_vector_test.cc"], copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, deps = [ + ":counting_allocator", ":inlined_vector", ":test_instance_tracker", "//absl/base", @@ -146,6 +155,7 @@ cc_test( srcs = ["inlined_vector_test.cc"], copts = ABSL_TEST_COPTS, deps = [ + ":counting_allocator", ":inlined_vector", ":test_instance_tracker", "//absl/base", @@ -443,6 +453,7 @@ cc_library( copts = ABSL_DEFAULT_COPTS, deps = [ ":have_sse", + "//absl/base", "//absl/base:core_headers", "//absl/debugging:stacktrace", "//absl/memory", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 4162d269..de9b22f7 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -122,6 +122,15 @@ absl_cc_library( PUBLIC ) +absl_cc_library( + NAME + counting_allocator + HDRS + "internal/counting_allocator.h" + COPTS + ${ABSL_DEFAULT_COPTS} +) + absl_cc_test( NAME inlined_vector_test @@ -132,6 +141,7 @@ absl_cc_test( LINKOPTS ${ABSL_EXCEPTIONS_FLAG_LINKOPTS} DEPS + absl::counting_allocator absl::inlined_vector absl::test_instance_tracker absl::base @@ -437,6 +447,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::base absl::have_sse absl::synchronization ) diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index fe228001..b6063441 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -795,79 +795,7 @@ class InlinedVector { void swap(InlinedVector& other) { if (ABSL_PREDICT_FALSE(this == &other)) return; - using std::swap; // Augment ADL with `std::swap`. - if (allocated() && other.allocated()) { - // Both out of line, so just swap the tag, allocation, and allocator. - swap(tag(), other.tag()); - swap(allocation(), other.allocation()); - swap(allocator(), other.allocator()); - return; - } - if (!allocated() && !other.allocated()) { - // Both inlined: swap up to smaller size, then move remaining elements. - InlinedVector* a = this; - InlinedVector* b = &other; - if (size() < other.size()) { - swap(a, b); - } - - const size_type a_size = a->size(); - const size_type b_size = b->size(); - assert(a_size >= b_size); - // `a` is larger. Swap the elements up to the smaller array size. - std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size, - b->inlined_space()); - - // Move the remaining elements: - // [`b_size`, `a_size`) from `a` -> [`b_size`, `a_size`) from `b` - b->UninitializedCopy(a->inlined_space() + b_size, - a->inlined_space() + a_size, - b->inlined_space() + b_size); - a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size); - - swap(a->tag(), b->tag()); - swap(a->allocator(), b->allocator()); - assert(b->size() == a_size); - assert(a->size() == b_size); - return; - } - - // One is out of line, one is inline. - // We first move the elements from the inlined vector into the - // inlined space in the other vector. We then put the other vector's - // pointer/capacity into the originally inlined vector and swap - // the tags. - InlinedVector* a = this; - InlinedVector* b = &other; - if (a->allocated()) { - swap(a, b); - } - assert(!a->allocated()); - assert(b->allocated()); - const size_type a_size = a->size(); - const size_type b_size = b->size(); - // In an optimized build, `b_size` would be unused. - static_cast(b_size); - - // Made Local copies of `size()`, don't need `tag()` accurate anymore - swap(a->tag(), b->tag()); - - // Copy `b_allocation` out before `b`'s union gets clobbered by - // `inline_space` - Allocation b_allocation = b->allocation(); - - b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size, - b->inlined_space()); - a->Destroy(a->inlined_space(), a->inlined_space() + a_size); - - a->allocation() = b_allocation; - - if (a->allocator() != b->allocator()) { - swap(a->allocator(), b->allocator()); - } - - assert(b->size() == a_size); - assert(a->size() == b_size); + SwapImpl(other); } private: @@ -1238,6 +1166,83 @@ class InlinedVector { return begin() + index; } + void SwapImpl(InlinedVector& other) { + using std::swap; // Augment ADL with `std::swap`. + + if (allocated() && other.allocated()) { + // Both out of line, so just swap the tag, allocation, and allocator. + swap(tag(), other.tag()); + swap(allocation(), other.allocation()); + swap(allocator(), other.allocator()); + return; + } + if (!allocated() && !other.allocated()) { + // Both inlined: swap up to smaller size, then move remaining elements. + InlinedVector* a = this; + InlinedVector* b = &other; + if (size() < other.size()) { + swap(a, b); + } + + const size_type a_size = a->size(); + const size_type b_size = b->size(); + assert(a_size >= b_size); + // `a` is larger. Swap the elements up to the smaller array size. + std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size, + b->inlined_space()); + + // Move the remaining elements: + // [`b_size`, `a_size`) from `a` -> [`b_size`, `a_size`) from `b` + b->UninitializedCopy(a->inlined_space() + b_size, + a->inlined_space() + a_size, + b->inlined_space() + b_size); + a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size); + + swap(a->tag(), b->tag()); + swap(a->allocator(), b->allocator()); + assert(b->size() == a_size); + assert(a->size() == b_size); + return; + } + + // One is out of line, one is inline. + // We first move the elements from the inlined vector into the + // inlined space in the other vector. We then put the other vector's + // pointer/capacity into the originally inlined vector and swap + // the tags. + InlinedVector* a = this; + InlinedVector* b = &other; + if (a->allocated()) { + swap(a, b); + } + assert(!a->allocated()); + assert(b->allocated()); + const size_type a_size = a->size(); + const size_type b_size = b->size(); + // In an optimized build, `b_size` would be unused. + static_cast(b_size); + + // Made Local copies of `size()`, don't need `tag()` accurate anymore + swap(a->tag(), b->tag()); + + // Copy `b_allocation` out before `b`'s union gets clobbered by + // `inline_space` + Allocation b_allocation = b->allocation(); + + b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size, + b->inlined_space()); + a->Destroy(a->inlined_space(), a->inlined_space() + a_size); + + a->allocation() = b_allocation; + + if (a->allocator() != b->allocator()) { + swap(a->allocator(), b->allocator()); + } + + assert(b->size() == a_size); + assert(a->size() == b_size); + } + // Stores either the inlined or allocated representation union Rep { using ValueTypeBuffer = diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 3a1ea8ac..b3dcc7f0 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -30,6 +30,7 @@ #include "absl/base/internal/exception_testing.h" #include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" +#include "absl/container/internal/counting_allocator.h" #include "absl/container/internal/test_instance_tracker.h" #include "absl/hash/hash_testing.h" #include "absl/memory/memory.h" @@ -37,6 +38,7 @@ namespace { +using absl::container_internal::CountingAllocator; using absl::test_internal::CopyableMovableInstance; using absl::test_internal::CopyableOnlyInstance; using absl::test_internal::InstanceTracker; @@ -138,57 +140,6 @@ static IntVec Fill(int len, int offset = 0) { return v; } -// This is a stateful allocator, but the state lives outside of the -// allocator (in whatever test is using the allocator). This is odd -// but helps in tests where the allocator is propagated into nested -// containers - that chain of allocators uses the same state and is -// thus easier to query for aggregate allocation information. -template -class CountingAllocator : public std::allocator { - public: - using Alloc = std::allocator; - using pointer = typename Alloc::pointer; - using size_type = typename Alloc::size_type; - - CountingAllocator() : bytes_used_(nullptr) {} - explicit CountingAllocator(int64_t* b) : bytes_used_(b) {} - - template - CountingAllocator(const CountingAllocator& x) - : Alloc(x), bytes_used_(x.bytes_used_) {} - - pointer allocate(size_type n, - std::allocator::const_pointer hint = nullptr) { - assert(bytes_used_ != nullptr); - *bytes_used_ += n * sizeof(T); - return Alloc::allocate(n, hint); - } - - void deallocate(pointer p, size_type n) { - Alloc::deallocate(p, n); - assert(bytes_used_ != nullptr); - *bytes_used_ -= n * sizeof(T); - } - - template - class rebind { - public: - using other = CountingAllocator; - }; - - friend bool operator==(const CountingAllocator& a, - const CountingAllocator& b) { - return a.bytes_used_ == b.bytes_used_; - } - - friend bool operator!=(const CountingAllocator& a, - const CountingAllocator& b) { - return !(a == b); - } - - int64_t* bytes_used_; -}; - TEST(IntVec, SimpleOps) { for (int len = 0; len < 20; len++) { IntVec v; diff --git a/absl/container/internal/counting_allocator.h b/absl/container/internal/counting_allocator.h new file mode 100644 index 00000000..f4e652d9 --- /dev/null +++ b/absl/container/internal/counting_allocator.h @@ -0,0 +1,79 @@ +// 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_CONTAINER_INTERNAL_COUNTING_ALLOCATOR_H_ +#define ABSL_CONTAINER_INTERNAL_COUNTING_ALLOCATOR_H_ + +#include +#include +#include + +namespace absl { +namespace container_internal { + +// This is a stateful allocator, but the state lives outside of the +// allocator (in whatever test is using the allocator). This is odd +// but helps in tests where the allocator is propagated into nested +// containers - that chain of allocators uses the same state and is +// thus easier to query for aggregate allocation information. +template +class CountingAllocator : public std::allocator { + public: + using Alloc = std::allocator; + using pointer = typename Alloc::pointer; + using size_type = typename Alloc::size_type; + + CountingAllocator() : bytes_used_(nullptr) {} + explicit CountingAllocator(int64_t* b) : bytes_used_(b) {} + + template + CountingAllocator(const CountingAllocator& x) + : Alloc(x), bytes_used_(x.bytes_used_) {} + + pointer allocate(size_type n, + std::allocator::const_pointer hint = nullptr) { + assert(bytes_used_ != nullptr); + *bytes_used_ += n * sizeof(T); + return Alloc::allocate(n, hint); + } + + void deallocate(pointer p, size_type n) { + Alloc::deallocate(p, n); + assert(bytes_used_ != nullptr); + *bytes_used_ -= n * sizeof(T); + } + + template + class rebind { + public: + using other = CountingAllocator; + }; + + friend bool operator==(const CountingAllocator& a, + const CountingAllocator& b) { + return a.bytes_used_ == b.bytes_used_; + } + + friend bool operator!=(const CountingAllocator& a, + const CountingAllocator& b) { + return !(a == b); + } + + int64_t* bytes_used_; +}; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_COUNTING_ALLOCATOR_H_ diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 6cc10c20..e588f24c 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -238,6 +238,10 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { return HashtablezSampler::Global().Register(); } +#if ABSL_PER_THREAD_TLS == 1 +ABSL_PER_THREAD_TLS_KEYWORD int64_t 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 4aea3ffa..c42f1842 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -31,6 +31,7 @@ #include #include +#include "absl/base/internal/per_thread_tls.h" #include "absl/base/optimization.h" #include "absl/synchronization/mutex.h" #include "absl/utility/utility.h" @@ -147,14 +148,16 @@ class HashtablezInfoHandle { // Returns an RAII sampling handle that manages registration and unregistation // with the global sampler. +#if ABSL_PER_THREAD_TLS == 1 +extern ABSL_PER_THREAD_TLS_KEYWORD int64_t next_sample; +#endif // ABSL_PER_THREAD_TLS + inline HashtablezInfoHandle Sample() { -#if ABSL_HAVE_THREAD_LOCAL - thread_local int64_t next_sample = 0; -#else // ABSL_HAVE_THREAD_LOCAL +#if ABSL_PER_THREAD_TLS == 0 static auto* mu = new absl::Mutex; static int64_t next_sample = 0; absl::MutexLock l(mu); -#endif // ABSL_HAVE_THREAD_LOCAL +#endif // !ABSL_HAVE_THREAD_LOCAL if (ABSL_PREDICT_TRUE(--next_sample > 0)) { return HashtablezInfoHandle(nullptr); diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 34d69d7a..8cdea4ec 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -785,7 +785,11 @@ class raw_hash_set { } ctrl_t* ctrl_ = nullptr; - slot_type* slot_; + // To avoid uninitialized member warnigs, put slot_ in an anonymous union. + // The member is not initialized on singleton and end iterators. + union { + slot_type* slot_; + }; }; class const_iterator { diff --git a/absl/copts/copts.py b/absl/copts/copts.py index 40a8062f..4da8442d 100644 --- a/absl/copts/copts.py +++ b/absl/copts/copts.py @@ -10,8 +10,6 @@ compilation options: The generated copts are consumed by configure_copts.bzl and AbseilConfigureCopts.cmake. """ - -import collections # absl:google-only(used for internal flags) COPT_VARS = { "GCC_FLAGS": [ "-Wall", diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 53e79884..43680046 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -69,6 +69,10 @@ cc_library( "notification.h", ], copts = ABSL_DEFAULT_COPTS, + linkopts = select({ + "//absl:windows": [], + "//conditions:default": ["-pthread"], + }), deps = [ ":graphcycles_internal", "//absl/base", @@ -245,10 +249,6 @@ cc_test( "lifetime_test.cc", ], copts = ABSL_TEST_COPTS, - linkopts = select({ - "//absl:windows": [], - "//conditions:default": ["-pthread"], - }), tags = ["no_test_ios_x86_64"], deps = [ ":synchronization", diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel index e2cfe801..a2053c97 100644 --- a/absl/time/internal/cctz/BUILD.bazel +++ b/absl/time/internal/cctz/BUILD.bazel @@ -98,13 +98,13 @@ cc_test( cc_test( name = "time_zone_lookup_test", size = "small", + timeout = "moderate", srcs = ["src/time_zone_lookup_test.cc"], data = [":zoneinfo"], tags = [ "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", - "no_test_wasm", ], deps = [ ":civil_time", 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 cd0ae23f..b99e1c63 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -64,17 +64,6 @@ void TestFormatSpecifier(time_point tp, time_zone tz, const std::string& fmt, EXPECT_EQ("xxx " + ans + " yyy", format("xxx " + fmt + " yyy", tp, tz)); } -// These tests sometimes run on platforms that have zoneinfo data so old -// that the transition we are attempting to check does not exist, most -// notably Android emulators. Fortunately, AndroidZoneInfoSource supports -// time_zone::version() so, in cases where we've learned that it matters, -// we can make the check conditionally. -int VersionCmp(time_zone tz, const std::string& target) { - std::string version = tz.version(); - if (version.empty() && !target.empty()) return 1; // unknown > known - return version.compare(target); -} - } // namespace // @@ -174,7 +163,9 @@ TEST(Format, PosixConversions) { TestFormatSpecifier(tp, tz, "%M", "00"); TestFormatSpecifier(tp, tz, "%S", "00"); TestFormatSpecifier(tp, tz, "%U", "00"); +#if !defined(__EMSCRIPTEN__) TestFormatSpecifier(tp, tz, "%w", "4"); // 4=Thursday +#endif TestFormatSpecifier(tp, tz, "%W", "00"); TestFormatSpecifier(tp, tz, "%y", "70"); TestFormatSpecifier(tp, tz, "%Y", "1970"); @@ -1464,6 +1455,10 @@ TEST(FormatParse, RoundTrip) { #if defined(_WIN32) || defined(_WIN64) // Initial investigations indicate the %c does not roundtrip on Windows. // TODO: Figure out what is going on here (perhaps a locale problem). +#elif defined(__EMSCRIPTEN__) + // strftime() and strptime() use different defintions for "%c" under + // emscripten (see https://github.com/kripken/emscripten/pull/7491), + // causing its round-trip test to fail. #else // Even though we don't know what %c will produce, it should roundtrip, // but only in the 0-offset timezone. 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 e84b9469..e9865659 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -666,6 +666,7 @@ int VersionCmp(time_zone tz, const std::string& target) { } // namespace +#if !defined(__EMSCRIPTEN__) TEST(TimeZones, LoadZonesConcurrently) { std::promise ready_promise; std::shared_future ready_future(ready_promise.get_future()); @@ -713,6 +714,7 @@ TEST(TimeZones, LoadZonesConcurrently) { } EXPECT_LE(failures.size(), max_failures) << testing::PrintToString(failures); } +#endif TEST(TimeZone, NamedTimeZones) { const time_zone utc = utc_time_zone(); diff --git a/absl/time/internal/cctz/testdata/version b/absl/time/internal/cctz/testdata/version index ac954d74..63f58006 100644 --- a/absl/time/internal/cctz/testdata/version +++ b/absl/time/internal/cctz/testdata/version @@ -1 +1 @@ -2018g-9-gf0d2759 +2018i diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome index d2a64bd1..59f3759c 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome and b/absl/time/internal/cctz/testdata/zoneinfo/Africa/Sao_Tome differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla index 26356078..85a7e16e 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla and b/absl/time/internal/cctz/testdata/zoneinfo/America/Metlakatla differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong index 8e5c5813..91eaff48 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong and b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Hong_Kong differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qostanay b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qostanay new file mode 100644 index 00000000..cb6e2d90 Binary files /dev/null and b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qostanay differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda index 00b27844..fc636b3b 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda and b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Qyzylorda differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran index ad9058b4..0ae2f65f 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran and b/absl/time/internal/cctz/testdata/zoneinfo/Asia/Tehran differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Hongkong b/absl/time/internal/cctz/testdata/zoneinfo/Hongkong index 8e5c5813..91eaff48 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Hongkong and b/absl/time/internal/cctz/testdata/zoneinfo/Hongkong differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Iran b/absl/time/internal/cctz/testdata/zoneinfo/Iran index ad9058b4..0ae2f65f 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Iran and b/absl/time/internal/cctz/testdata/zoneinfo/Iran differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein b/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein index 54bd71ff..d6413577 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein and b/absl/time/internal/cctz/testdata/zoneinfo/Kwajalein differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk index e79bca2d..8004d65b 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Chuuk differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam index ffdf8c24..e2242475 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Guam differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae index b6bd4b08..11583b13 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kosrae differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein index 54bd71ff..d6413577 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Kwajalein differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro index 53f32886..65990cbb 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Majuro differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru index 7e7d920e..86d3b7d1 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Nauru differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau index 968f1956..05633b88 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Palau differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei index d3393a20..090429c0 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Pohnpei differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape index d3393a20..090429c0 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Ponape differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan index ffdf8c24..e2242475 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Saipan differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk index e79bca2d..8004d65b 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Truk differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap index e79bca2d..8004d65b 100644 Binary files a/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap and b/absl/time/internal/cctz/testdata/zoneinfo/Pacific/Yap differ diff --git a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab index 2729e6e8..9a8e4244 100644 --- a/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab +++ b/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab @@ -211,6 +211,7 @@ KP +3901+12545 Asia/Pyongyang KR +3733+12658 Asia/Seoul KZ +4315+07657 Asia/Almaty Kazakhstan (most areas) KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda +KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay KZ +5017+05710 Asia/Aqtobe Aqtöbe/Aktobe KZ +4431+05016 Asia/Aqtau Mangghystaū/Mankistau KZ +4707+05156 Asia/Atyrau Atyraū/Atirau/Gur'yev -- cgit v1.2.3 From 018b4db1d73ec8238e6dc4b17fd9e1fd7468d0ed Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 9 Jan 2019 09:55:36 -0800 Subject: Export of internal Abseil changes. -- fd86c60bac6c41f1629ce1ab7dc1c8edff398a59 by Alex Strelnikov : Import PR: https://github.com/abseil/abseil-cpp/pull/243 Fix Windows ARM64 intrinsic use. PiperOrigin-RevId: 228535649 -- a0ca663f606a3b31493683e405be2b1cff450894 by CJ Johnson : Fixes issue of mixed signedness comparison PiperOrigin-RevId: 228535623 -- d71aaa1705d7303b43fe02088fe07b153e647796 by Shaindel Schwartz : Import of CCTZ from GitHub. PiperOrigin-RevId: 228534365 -- c1b49d361aa880198e071f93997724bddbcd4760 by Samuel Benzaquen : Internal cleanup PiperOrigin-RevId: 228406627 -- 0c4b1c2bed107698e209055b3431771d7a1bdba1 by Dave Walker : Add comments about the purpose of container_internal::slot_type. PiperOrigin-RevId: 228264537 -- 060aa6077d2f3a0a129149e0644d19f2f521b241 by Abseil Team : #include in hashtablez_sampler.cc Expected to fix the android build. PiperOrigin-RevId: 228222550 GitOrigin-RevId: fd86c60bac6c41f1629ce1ab7dc1c8edff398a59 Change-Id: I26339fd4548c1a81b037cb52c26910d1bd850ea8 --- absl/container/BUILD.bazel | 10 +++++ absl/container/CMakeLists.txt | 12 ++++++ absl/container/internal/common.h | 48 ++++++++++++++++++++++ absl/container/internal/container_memory.h | 27 ++++++++++-- absl/container/internal/hashtablez_sampler.cc | 1 + absl/container/internal/raw_hash_map.h | 4 +- absl/container/internal/raw_hash_set.h | 29 ++----------- absl/synchronization/internal/thread_pool.h | 3 +- absl/time/internal/cctz/BUILD.bazel | 2 + absl/time/internal/cctz/src/cctz_benchmark.cc | 1 + .../internal/cctz/src/time_zone_lookup_test.cc | 1 + 11 files changed, 105 insertions(+), 33 deletions(-) create mode 100644 absl/container/internal/common.h (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 623faf45..87fc7349 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -510,12 +510,22 @@ cc_library( visibility = ["//visibility:private"], ) +cc_library( + name = "common", + hdrs = ["internal/common.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + "//absl/meta:type_traits", + ], +) + cc_library( name = "raw_hash_set", srcs = ["internal/raw_hash_set.cc"], hdrs = ["internal/raw_hash_set.h"], copts = ABSL_DEFAULT_COPTS, deps = [ + ":common", ":compressed_tuple", ":container_memory", ":hash_policy_traits", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index de9b22f7..21c9cb95 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -527,6 +527,17 @@ absl_cc_library( PUBLIC ) +absl_cc_library( + NAME + container_common + HDRS + "internal/commom.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::type_traits +) + absl_cc_library( NAME raw_hash_set @@ -540,6 +551,7 @@ absl_cc_library( absl::bits absl::compressed_tuple absl::config + absl::container_common absl::container_memory absl::core_headers absl::endian diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h new file mode 100644 index 00000000..a6dc9103 --- /dev/null +++ b/absl/container/internal/common.h @@ -0,0 +1,48 @@ +// 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_H_ +#define ABSL_CONTAINER_INTERNAL_CONTAINER_H_ + +#include + +#include "absl/meta/type_traits.h" + +namespace absl { +namespace container_internal { + +template +struct IsTransparent : std::false_type {}; +template +struct IsTransparent> + : std::true_type {}; + +template +struct KeyArg { + // Transparent. Forward `K`. + template + using type = K; +}; + +template <> +struct KeyArg { + // Not transparent. Always use `key_type`. + template + using type = key_type; +}; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_CONTAINER_H_ diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index 56c5d2df..35b691ce 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -286,11 +286,30 @@ struct IsLayoutCompatible { } // namespace memory_internal -// If kMutableKeys is false, only the value member is accessed. +// The internal storage type for key-value containers like flat_hash_map. // -// If kMutableKeys is true, key is accessed through all slots while value and -// mutable_value are accessed only via INITIALIZED slots. Slots are created and -// destroyed via mutable_value so that the key can be moved later. +// It is convenient for the value_type of a flat_hash_map to be +// pair; the "const K" prevents accidental modification of the key +// when dealing with the reference returned from find() and similar methods. +// However, this creates other problems; we want to be able to emplace(K, V) +// efficiently with move operations, and similarly be able to move a +// pair in insert(). +// +// The solution is this union, which aliases the const and non-const versions +// of the pair. This also allows flat_hash_map to work, even though +// that has the same efficiency issues with move in emplace() and insert() - +// but people do it anyway. +// +// If kMutableKeys is false, only the value member can be accessed. +// +// If kMutableKeys is true, key can be accessed through all slots while value +// and mutable_value must be accessed only via INITIALIZED slots. Slots are +// created and destroyed via mutable_value so that the key can be moved later. +// +// Accessing one of the union fields while the other is active is safe as +// long as they are layout-compatible, which is guaranteed by the definition of +// kMutableKeys. For C++11, the relevant section of the standard is +// https://timsong-cpp.github.io/cppwp/n3337/class.mem#19 (9.2.19) template union slot_type { private: diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index e588f24c..1ba95645 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index 05270ef3..e0f5c07c 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h @@ -39,8 +39,8 @@ class raw_hash_map : public raw_hash_set { using MappedConstReference = decltype(P::value( std::addressof(std::declval()))); - using KeyArgImpl = container_internal::KeyArg::value && - IsTransparent::value>; + using KeyArgImpl = + KeyArg::value && IsTransparent::value>; public: using key_type = typename Policy::key_type; diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 8cdea4ec..8f2350a7 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -105,6 +105,7 @@ #include "absl/base/internal/bits.h" #include "absl/base/internal/endian.h" #include "absl/base/port.h" +#include "absl/container/internal/common.h" #include "absl/container/internal/compressed_tuple.h" #include "absl/container/internal/container_memory.h" #include "absl/container/internal/hash_policy_traits.h" @@ -165,12 +166,6 @@ struct IsDecomposable< std::declval()...))>, Policy, Hash, Eq, Ts...> : std::true_type {}; -template -struct IsTransparent : std::false_type {}; -template -struct IsTransparent> - : std::true_type {}; - // TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it. template constexpr bool IsNoThrowSwappable() { @@ -605,24 +600,6 @@ struct insert_return_type { NodeType node; }; -// Helper trait to allow or disallow arbitrary keys when the hash and -// eq functions are transparent. -// It is very important that the inner template is an alias and that the type it -// produces is not a dependent type. Otherwise, type deduction would fail. -template -struct KeyArg { - // Transparent. Forward `K`. - template - using type = K; -}; - -template <> -struct KeyArg { - // Not transparent. Always use `key_type`. - template - using type = key_type; -}; - // Policy: a policy defines how to perform different operations on // the slots of the hashtable (see hash_policy_traits.h for the full interface // of policy). @@ -643,8 +620,8 @@ struct KeyArg { template class raw_hash_set { using PolicyTraits = hash_policy_traits; - using KeyArgImpl = container_internal::KeyArg::value && - IsTransparent::value>; + using KeyArgImpl = + KeyArg::value && IsTransparent::value>; public: using init_type = typename PolicyTraits::init_type; diff --git a/absl/synchronization/internal/thread_pool.h b/absl/synchronization/internal/thread_pool.h index 84640427..c753a68d 100644 --- a/absl/synchronization/internal/thread_pool.h +++ b/absl/synchronization/internal/thread_pool.h @@ -16,6 +16,7 @@ #define ABSL_SYNCHRONIZATION_INTERNAL_THREAD_POOL_H_ #include +#include #include #include #include // NOLINT(build/c++11) @@ -42,7 +43,7 @@ class ThreadPool { ~ThreadPool() { { absl::MutexLock l(&mu_); - for (int i = 0; i < threads_.size(); ++i) { + for (size_t i = 0; i < threads_.size(); i++) { queue_.push(nullptr); // Shutdown signal. } } diff --git a/absl/time/internal/cctz/BUILD.bazel b/absl/time/internal/cctz/BUILD.bazel index a2053c97..1fb33c20 100644 --- a/absl/time/internal/cctz/BUILD.bazel +++ b/absl/time/internal/cctz/BUILD.bazel @@ -87,6 +87,7 @@ cc_test( "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", + "no_test_wasm", ], deps = [ ":civil_time", @@ -105,6 +106,7 @@ cc_test( "no_test_android_arm", "no_test_android_arm64", "no_test_android_x86", + "no_test_wasm", ], deps = [ ":civil_time", diff --git a/absl/time/internal/cctz/src/cctz_benchmark.cc b/absl/time/internal/cctz/src/cctz_benchmark.cc index 4498d7d0..a00f47bf 100644 --- a/absl/time/internal/cctz/src/cctz_benchmark.cc +++ b/absl/time/internal/cctz/src/cctz_benchmark.cc @@ -357,6 +357,7 @@ const char* const kTimeZoneNames[] = { "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", + "Asia/Qostanay", "Asia/Qyzylorda", "Asia/Rangoon", "Asia/Riyadh", 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 e9865659..3dca822c 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -337,6 +337,7 @@ const char* const kTimeZoneNames[] = { "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", + "Asia/Qostanay", "Asia/Qyzylorda", "Asia/Rangoon", "Asia/Riyadh", -- cgit v1.2.3 From 0dffca4e36791c7beeda04da10460b534283948a Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 24 Jan 2019 07:23:40 -0800 Subject: Export of internal Abseil changes. -- 5804cc13b413412988248835459b90cd15ec43d9 by Abseil Team : Mark raw_hash_set::clear() with the ABSL_ATTRIBUTE_REINITIALIZES attribute. This prevents false positives in the clang-tidy check bugprone-use-after-move; it allows reset() to be called on a moved-from raw_hash_set without any warnings, and the raw_hash_set will thereafter be regarded as initialized again. PiperOrigin-RevId: 230717196 -- ff5961a5600ae19b69a9cba6912126cdf2858f38 by CJ Johnson : Swaps DisableIfIntegral<> for EnableIfInputIterator<> for Iterator member functions of InlinedVector PiperOrigin-RevId: 230559521 -- 3f9754ccbeecbd40f235c6f2465279e045ff51d9 by Derek Mauro : Import GitHub PR 254 https://github.com/abseil/abseil-cpp/pull/254 Fixes warnings from -Wclass-memaccess (base_internal::ThreadIdentity? with no trivial copy-assignment). PiperOrigin-RevId: 230536048 -- 8af03a654ce9a4a7f55384bc7eb1ed64878ac2ec by Chris Kennelly : absl: cap SpinLock backoff to 4ms The current backoff logic has 3 problems: 1. It can produce too high values (up to 256ms), which can negatively affect tail latency. The value was chosen long time ago and now it's a good idea to reconsider it. 2. It does not have low bound, so on any iteration it can produce a very small value that will lead to unnecessary cpu consumption. 3. It does not increase low bound with the number of iterations. So if the SpinLock is actually somehow locked for a very prolonged time, a waiter can still wake periodically. Rework the logic to solve these problems. Add lower bound of 128us, no code should rely on absence of episodic delays in this range as they can occur everywhere. Lower upper bound to 4ms. A thread sleeping for 4ms does not consume significant cpu time (see below). Grow lower bound with the number of iterations. This is cpu consumption of a process doing usleep(x) in a loop (sampled with ps): 64us -> 4.0% 128us -> 2.7% 256us -> 3.5% 512us -> 2.8% 1024us -> 1.6% 2048us -> 0.6% 4096us -> 0.3% 8192us -> 0.0% Few millisecond sleeps do not consume significant time. PiperOrigin-RevId: 230534015 -- 37ebba92289ca556cb2412cd8b3cb4c1ead3def7 by Samuel Benzaquen : Add override and dispose hooks to the hashtable sampler. PiperOrigin-RevId: 230353438 -- 89c8f90175233ce9964eb3412df04e8a3cff0c0f by Andy Getzendanner : Fix a comment typo. PiperOrigin-RevId: 229986838 GitOrigin-RevId: 5804cc13b413412988248835459b90cd15ec43d9 Change-Id: Iedb5e2cc9c0b924635c1c87b537780ab6b5b899f --- absl/base/internal/spinlock_linux.inc | 17 +++--- absl/base/internal/spinlock_wait.cc | 13 ++--- absl/container/BUILD.bazel | 28 +++++++++- absl/container/CMakeLists.txt | 25 +++++++++ absl/container/inlined_vector.h | 10 ++-- .../internal/hashtablez_force_sampling.cc | 24 +++++++++ .../internal/hashtablez_force_sampling_test.cc | 60 ++++++++++++++++++++++ absl/container/internal/hashtablez_sampler.cc | 16 +++++- absl/container/internal/hashtablez_sampler.h | 16 ++++++ .../hashtablez_sampler_force_weak_definition.cc | 27 ++++++++++ absl/container/internal/hashtablez_sampler_test.cc | 25 +++++++++ absl/container/internal/raw_hash_set.h | 2 +- absl/time/clock.cc | 2 +- 13 files changed, 236 insertions(+), 29 deletions(-) create mode 100644 absl/container/internal/hashtablez_force_sampling.cc create mode 100644 absl/container/internal/hashtablez_force_sampling_test.cc create mode 100644 absl/container/internal/hashtablez_sampler_force_weak_definition.cc (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc index 94c861dc..3bbd4954 100644 --- a/absl/base/internal/spinlock_linux.inc +++ b/absl/base/internal/spinlock_linux.inc @@ -51,17 +51,12 @@ extern "C" { ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode) { - if (loop != 0) { - int save_errno = errno; - struct timespec tm; - tm.tv_sec = 0; - // Increase the delay; we expect (but do not rely on) explicit wakeups. - // We don't rely on explicit wakeups because we intentionally allow for - // a race on the kSpinLockSleeper bit. - tm.tv_nsec = 16 * absl::base_internal::SpinLockSuggestedDelayNS(loop); - syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm); - errno = save_errno; - } + int save_errno = errno; + struct timespec tm; + tm.tv_sec = 0; + tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); + syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm); + errno = save_errno; } ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic *w, diff --git a/absl/base/internal/spinlock_wait.cc b/absl/base/internal/spinlock_wait.cc index 365a7939..7e4f4352 100644 --- a/absl/base/internal/spinlock_wait.cc +++ b/absl/base/internal/spinlock_wait.cc @@ -65,17 +65,14 @@ int SpinLockSuggestedDelayNS(int loop) { r = 0x5deece66dLL * r + 0xb; // numbers from nrand48() delay_rand.store(r, std::memory_order_relaxed); - r <<= 16; // 48-bit random number now in top 48-bits. if (loop < 0 || loop > 32) { // limit loop to 0..32 loop = 32; } - // loop>>3 cannot exceed 4 because loop cannot exceed 32. - // Select top 20..24 bits of lower 48 bits, - // giving approximately 0ms to 16ms. - // Mean is exponential in loop for first 32 iterations, then 8ms. - // The futex path multiplies this by 16, since we expect explicit wakeups - // almost always on that path. - return static_cast(r >> (44 - (loop >> 3))); + const int kMinDelay = 128 << 10; // 128us + // Double delay every 8 iterations, up to 16x (2ms). + int delay = kMinDelay << (loop / 8); + // Randomize in delay..2*delay range, for resulting 128us..4ms range. + return delay | ((delay - 1) & static_cast(r)); } } // namespace base_internal diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 87fc7349..acdbc473 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -446,9 +446,21 @@ cc_library( copts = ABSL_DEFAULT_COPTS, ) +cc_library( + name = "hashtablez_force_sampling", + srcs = ["internal/hashtablez_force_sampling.cc"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":hashtablez_sampler", + ], +) + cc_library( name = "hashtablez_sampler", - srcs = ["internal/hashtablez_sampler.cc"], + srcs = [ + "internal/hashtablez_sampler.cc", + "internal/hashtablez_sampler_force_weak_definition.cc", + ], hdrs = ["internal/hashtablez_sampler.h"], copts = ABSL_DEFAULT_COPTS, deps = [ @@ -476,6 +488,20 @@ cc_test( ], ) +cc_test( + name = "hashtablez_force_sampling_test", + srcs = ["internal/hashtablez_force_sampling_test.cc"], + tags = [ + "no_test_darwin_x86_64", + "no_test_msvc_x64", + ], + deps = [ + ":hashtablez_force_sampling", + ":hashtablez_sampler", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "node_hash_policy", hdrs = ["internal/node_hash_policy.h"], diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 21c9cb95..822388bd 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -444,6 +444,7 @@ absl_cc_library( "internal/hashtablez_sampler.h" SRCS "internal/hashtablez_sampler.cc" + "internal/hashtablez_sampler_force_weak_definition.cc" COPTS ${ABSL_DEFAULT_COPTS} DEPS @@ -463,6 +464,30 @@ absl_cc_test( gmock_main ) +absl_cc_library( + NAME + hashtablez_force_sampling + SRCS + "internal/hashtablez_force_sampling.cc" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::base + absl::have_sse + absl::synchronization +) + +absl_cc_test( + NAME + hashtablez_force_sampling_test + SRCS + "internal/hashtablez_force_sampling_test.cc" + DEPS + absl::hashtablez_force_sampling + absl::hashtablez_sampler + gmock_main +) + absl_cc_library( NAME hashtable_debug diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 649e904a..6625d43f 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -81,10 +81,6 @@ class InlinedVector { typename std::iterator_traits::iterator_category, std::forward_iterator_tag>; - template - using DisableIfIntegral = - absl::enable_if_t::value>; - template using EnableIfAtLeastInputIterator = absl::enable_if_t::value>; @@ -152,7 +148,8 @@ class InlinedVector { // NOTE: The `enable_if` prevents ambiguous interpretation between a call to // this constructor with two integral arguments and a call to the above // `InlinedVector(size_type, const_reference)` constructor. - template * = nullptr> + template * = nullptr> InlinedVector(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) : allocator_and_tag_(alloc) { @@ -516,7 +513,8 @@ class InlinedVector { // Overload of `InlinedVector::assign()` to replace the contents of the // inlined vector with values constructed from the range [`first`, `last`). - template * = nullptr> + template * = nullptr> void assign(InputIterator first, InputIterator last) { AssignRange(first, last); } diff --git a/absl/container/internal/hashtablez_force_sampling.cc b/absl/container/internal/hashtablez_force_sampling.cc new file mode 100644 index 00000000..868976ec --- /dev/null +++ b/absl/container/internal/hashtablez_force_sampling.cc @@ -0,0 +1,24 @@ +// 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 +// +// http://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/container/internal/hashtablez_sampler.h" + +namespace absl { +namespace container_internal { + +// See hashtablez_sampler.h for details. +extern "C" const bool kAbslContainerInternalSampleEverything = true; + +} // namespace container_internal +} // namespace absl diff --git a/absl/container/internal/hashtablez_force_sampling_test.cc b/absl/container/internal/hashtablez_force_sampling_test.cc new file mode 100644 index 00000000..9ff1046a --- /dev/null +++ b/absl/container/internal/hashtablez_force_sampling_test.cc @@ -0,0 +1,60 @@ +// 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 +// +// http://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 "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/container/internal/hashtablez_sampler.h" + +namespace absl { +namespace container_internal { + +class HashtablezInfoHandlePeer { + public: + static bool IsSampled(const HashtablezInfoHandle& h) { + return h.info_ != nullptr; + } +}; + +namespace { + +bool samples[3]{true, true, true}; + +// We do this test in a global object to test that this works even before main. +struct Global { + Global() { + // By default it is sampled. + samples[0] = HashtablezInfoHandlePeer::IsSampled(Sample()); + + // Even with a large parameter, it is sampled. + SetHashtablezSampleParameter(100); + samples[1] = HashtablezInfoHandlePeer::IsSampled(Sample()); + + // Even if we turn it off, it is still sampled. + SetHashtablezEnabled(false); + samples[2] = HashtablezInfoHandlePeer::IsSampled(Sample()); + } +} global; + +TEST(kAbslContainerInternalSampleEverything, Works) { + EXPECT_THAT(samples, testing::Each(true)); + EXPECT_TRUE(kAbslContainerInternalSampleEverything); + // One more after main() + EXPECT_TRUE(HashtablezInfoHandlePeer::IsSampled(Sample())); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 1ba95645..7c411140 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -116,6 +116,11 @@ HashtablezSampler& HashtablezSampler::Global() { return *sampler; } +HashtablezSampler::DisposeCallback HashtablezSampler::SetDisposeCallback( + DisposeCallback f) { + return dispose_.exchange(f, std::memory_order_relaxed); +} + HashtablezInfo::HashtablezInfo() { PrepareForSampling(); } HashtablezInfo::~HashtablezInfo() = default; @@ -138,7 +143,7 @@ void HashtablezInfo::PrepareForSampling() { } HashtablezSampler::HashtablezSampler() - : dropped_samples_(0), size_estimate_(0), all_(nullptr) { + : dropped_samples_(0), size_estimate_(0), all_(nullptr), dispose_(nullptr) { absl::MutexLock l(&graveyard_.init_mu); graveyard_.dead = &graveyard_; } @@ -161,6 +166,10 @@ void HashtablezSampler::PushNew(HashtablezInfo* sample) { } void HashtablezSampler::PushDead(HashtablezInfo* sample) { + if (auto* dispose = dispose_.load(std::memory_order_relaxed)) { + dispose(*sample); + } + absl::MutexLock graveyard_lock(&graveyard_.init_mu); absl::MutexLock sample_lock(&sample->init_mu); sample->dead = graveyard_.dead; @@ -220,6 +229,11 @@ int64_t HashtablezSampler::Iterate( } HashtablezInfo* SampleSlow(int64_t* next_sample) { + if (kAbslContainerInternalSampleEverything) { + *next_sample = 1; + return HashtablezSampler::Global().Register(); + } + bool first = *next_sample < 0; *next_sample = GetGeometricVariable( g_hashtablez_sample_parameter.load(std::memory_order_relaxed)); diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index c42f1842..126a0ade 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -183,6 +183,13 @@ class HashtablezSampler { // Unregisters the sample. void Unregister(HashtablezInfo* sample); + // The dispose callback will be called on all samples the moment they are + // being unregistered. Only affects samples that are unregistered after the + // callback has been set. + // Returns the previous callback. + using DisposeCallback = void (*)(const HashtablezInfo&); + DisposeCallback SetDisposeCallback(DisposeCallback f); + // Iterates over all the registered `StackInfo`s. Returning the number of // samples that have been dropped. int64_t Iterate(const std::function& f); @@ -222,6 +229,8 @@ class HashtablezSampler { // std::atomic all_; HashtablezInfo graveyard_; + + std::atomic dispose_; }; // Enables or disables sampling for Swiss tables. @@ -233,6 +242,13 @@ void SetHashtablezSampleParameter(int32_t rate); // Sets a soft max for the number of samples that will be kept. void SetHashtablezMaxSamples(int32_t max); +// Configuration override. +// This allows process-wide sampling without depending on order of +// initialization of static storage duration objects. +// The definition of this constant is weak, which allows us to inject a +// different value for it at link time. +extern "C" const bool kAbslContainerInternalSampleEverything; + } // namespace container_internal } // namespace absl diff --git a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc new file mode 100644 index 00000000..38a3f260 --- /dev/null +++ b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -0,0 +1,27 @@ +// 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 +// +// http://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/container/internal/hashtablez_sampler.h" + +#include "absl/base/attributes.h" + +namespace absl { +namespace container_internal { + +// See hashtablez_sampler.h for details. +extern "C" ABSL_ATTRIBUTE_WEAK const bool + kAbslContainerInternalSampleEverything = false; + +} // namespace container_internal +} // namespace absl diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 31e7641a..f9ee941a 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -302,6 +302,31 @@ TEST(HashtablezSamplerTest, MultiThreaded) { stop.Notify(); } +TEST(HashtablezSamplerTest, Callback) { + HashtablezSampler sampler; + + auto* info1 = Register(&sampler, 1); + auto* info2 = Register(&sampler, 2); + + static const HashtablezInfo* expected; + + auto callback = [](const HashtablezInfo& info) { + // We can't use `info` outside of this callback because the object will be + // disposed as soon as we return from here. + EXPECT_EQ(&info, expected); + }; + + // Set the callback. + EXPECT_EQ(sampler.SetDisposeCallback(callback), nullptr); + expected = info1; + sampler.Unregister(info1); + + // Unset the callback. + EXPECT_EQ(callback, sampler.SetDisposeCallback(nullptr)); + expected = nullptr; // no more calls. + sampler.Unregister(info2); +} + } // namespace } // namespace container_internal } // namespace absl diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 8f6469ff..8e3fa02d 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -1035,7 +1035,7 @@ class raw_hash_set { size_t capacity() const { return capacity_; } size_t max_size() const { return (std::numeric_limits::max)(); } - void clear() { + ABSL_ATTRIBUTE_REINITIALIZES void clear() { // Iterating over this container is O(bucket_count()). When bucket_count() // is much greater than size(), iteration becomes prohibitively expensive. // For clear() it is more important to reuse the allocated array when the diff --git a/absl/time/clock.cc b/absl/time/clock.cc index 74ee1401..4863f643 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -379,7 +379,7 @@ static uint64_t UpdateLastSample( // // Manually mark this 'noinline' to minimize stack frame size of the fast // path. Without this, sometimes a compiler may inline this big block of code -// into the fast past. That causes lots of register spills and reloads that +// into the fast path. That causes lots of register spills and reloads that // are unnecessary unless the slow path is taken. // // TODO(absl-team): Remove this attribute when our compiler is smart enough -- cgit v1.2.3 From a4cb1c8ba61531a63f9d309eea01ac1d43d8371d Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 30 Jan 2019 10:59:43 -0800 Subject: Export of internal Abseil changes. -- 6fdf24a197b964f9bacbebd0ceca305aef1654fc by Shaindel Schwartz : Internal change PiperOrigin-RevId: 231627312 -- 65f7faf52bff01384171efb85fee159378dedf70 by CJ Johnson : Relocates the definitions of the InputIterator-accepting parts of the InlinedVector API into the top-level. The removed functions had no other callers so there was no reason to keep the layer of indirection in the form of the function call. PiperOrigin-RevId: 231527459 -- 30e105b749b5ecc50fdaf26c7da589617efce425 by CJ Johnson : Relocates closing brace for absl namespace in InlinedVector to the correct end location PiperOrigin-RevId: 231477871 -- 063c1e8b9d1f032662c46d574e20ecc357b87d0c by Eric Fiselier : Cleanup std::hash probing metafunctions. Previously there were two different ways to probe for std::hash. One in hash.h and another in type_traits.h, and they were both implemented differently, and neither correctly worked around bad STL implementations. This patch unifies the implementations into a single IsHashable trait. It also: * Correctly checks for old libc++ versions where this won't work. * Avoids undefined behavior which resulted from calling std::is_constructible incomplete types. * Unifies the feature test macro used in the headers and the tests. Additionally it also slightly changes the behavior of when absl::variant is hashable. Previously we disable hashing when std::hash()(key) was formed but when std::hash couldn't be destructed. This seems wrong. If a user provides a evil specialization of std::hash, then it's OK for variant's hash to blow up. PiperOrigin-RevId: 231468345 -- 05d75dd4b07c893de9b104731644d0d207b01253 by Abseil Team : Import of CCTZ from GitHub. PiperOrigin-RevId: 231397518 -- a0ee9032f9e04039f3410ed17fcf45ae1a3868f5 by CJ Johnson : Remove unused EnableIfAtLeastInputIterator from InlinedVector PiperOrigin-RevId: 231348903 -- 4dcd4e9a6780a81d7a6974c7bf22a037e6482b49 by Abseil Team : Remove unnecessary register keyword from absl/base/internal/endian.h. PiperOrigin-RevId: 231316570 -- c8584836caa3a10f90a8604a85d4b831310b72ee by Abseil Team : Fix hashtablez_sampler compilation on older Android NDK builds PiperOrigin-RevId: 231283542 GitOrigin-RevId: 6fdf24a197b964f9bacbebd0ceca305aef1654fc Change-Id: I185b12fb8347e3ad0ffcb2cbb83a53450e5eb938 --- absl/base/internal/endian.h | 2 +- absl/base/macros.h | 1 - absl/container/inlined_vector.h | 62 +--- absl/container/internal/hashtablez_sampler.cc | 2 +- absl/hash/hash_test.cc | 331 ++++++++++++++++++++- absl/hash/internal/hash.h | 19 +- absl/hash/internal/spy_hash_state.h | 2 +- absl/meta/type_traits.h | 72 ++++- .../internal/cctz/src/time_zone_lookup_test.cc | 2 +- absl/types/internal/variant.h | 3 +- absl/types/optional.h | 1 + absl/types/optional_test.cc | 21 +- absl/types/variant_test.cc | 35 +-- 13 files changed, 435 insertions(+), 118 deletions(-) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index d5dc51ad..3f59184a 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h @@ -75,7 +75,7 @@ inline uint64_t gbswap_64(uint64_t host_int) { if (__builtin_constant_p(host_int)) { return __bswap_constant_64(host_int); } else { - register uint64_t result; + uint64_t result; __asm__("bswap %0" : "=r"(result) : "0"(host_int)); return result; } diff --git a/absl/base/macros.h b/absl/base/macros.h index 9e7ab375..5ed12cb0 100644 --- a/absl/base/macros.h +++ b/absl/base/macros.h @@ -24,7 +24,6 @@ // This code is compiled directly on many platforms, including client // platforms like Windows, Mac, and embedded systems. Before making // any changes here, make sure that you're not breaking any platforms. -// #ifndef ABSL_BASE_MACROS_H_ #define ABSL_BASE_MACROS_H_ diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index e0f1714c..493bd8eb 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -71,20 +71,11 @@ class InlinedVector { return static_cast(N); } - template - using IsAtLeastInputIterator = std::is_convertible< - typename std::iterator_traits::iterator_category, - std::input_iterator_tag>; - template using IsAtLeastForwardIterator = std::is_convertible< typename std::iterator_traits::iterator_category, std::forward_iterator_tag>; - template - using EnableIfAtLeastInputIterator = - absl::enable_if_t::value>; - template using EnableIfAtLeastForwardIterator = absl::enable_if_t::value>; @@ -163,7 +154,7 @@ class InlinedVector { InlinedVector(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) : allocator_and_tag_(alloc) { - AppendInputRange(first, last); + std::copy(first, last, std::back_inserter(*this)); } // Creates a copy of `other` using `other`'s allocator. @@ -534,7 +525,13 @@ class InlinedVector { template * = nullptr> void assign(InputIterator first, InputIterator last) { - AssignInputRange(first, last); + size_type assign_index = 0; + for (; (assign_index < size()) && (first != last); + static_cast(++assign_index), static_cast(++first)) { + *(data() + assign_index) = *first; + } + erase(data() + assign_index, data() + size()); + std::copy(first, last, std::back_inserter(*this)); } // `InlinedVector::resize()` @@ -630,7 +627,12 @@ class InlinedVector { template * = nullptr> iterator insert(const_iterator pos, InputIterator first, InputIterator last) { - return InsertWithInputRange(pos, first, last); + size_type initial_insert_index = std::distance(cbegin(), pos); + for (size_type insert_index = initial_insert_index; first != last; + static_cast(++insert_index), static_cast(++first)) { + insert(data() + insert_index, *first); + } + return iterator(data() + initial_insert_index); } // `InlinedVector::emplace()` @@ -1131,20 +1133,6 @@ class InlinedVector { } } - template - void AssignInputRange(InputIterator first, InputIterator last) { - static_assert(IsAtLeastInputIterator::value, ""); - - // Optimized to avoid reallocation. - // Prefer reassignment to copy construction for elements. - iterator out = begin(); - for (; first != last && out != end(); ++first, ++out) { - *out = *first; - } - erase(out, end()); - std::copy(first, last, std::back_inserter(*this)); - } - template void AppendForwardRange(ForwardIterator first, ForwardIterator last) { static_assert(IsAtLeastForwardIterator::value, ""); @@ -1160,13 +1148,6 @@ class InlinedVector { } } - template - void AppendInputRange(InputIterator first, InputIterator last) { - static_assert(IsAtLeastInputIterator::value, ""); - - std::copy(first, last, std::back_inserter(*this)); - } - iterator InsertWithCount(const_iterator position, size_type n, const_reference v) { assert(position >= begin() && position <= end()); @@ -1198,18 +1179,6 @@ class InlinedVector { return it_pair.first; } - template - iterator InsertWithInputRange(const_iterator position, InputIterator first, - InputIterator last) { - static_assert(IsAtLeastInputIterator::value, ""); - assert(position >= begin() && position <= end()); - - size_type index = position - cbegin(); - size_type i = index; - while (first != last) insert(begin() + i++, *first++); - return begin() + index; - } - void SwapImpl(InlinedVector& other) { using std::swap; // Augment ADL with `std::swap`. @@ -1393,6 +1362,7 @@ auto AbslHashValue(H h, const InlinedVector& v) -> H { auto n = v.size(); return H::combine(H::combine_contiguous(std::move(h), p, n), n); } +} // namespace absl // ----------------------------------------------------------------------------- // Implementation of InlinedVector @@ -1400,6 +1370,4 @@ auto AbslHashValue(H h, const InlinedVector& v) -> H { // Do not depend on any below implementation details! // ----------------------------------------------------------------------------- -} // namespace absl - #endif // ABSL_CONTAINER_INLINED_VECTOR_H_ diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 7c411140..99cd8344 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -93,7 +93,7 @@ int64_t GetGeometricVariable(int64_t mean) { // 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 = (std::log2(q) - 26) * (-std::log(2.0) * mean); + 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 diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 224832b1..a5af93ad 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -15,6 +15,7 @@ #include "absl/hash/hash.h" #include +#include #include #include #include @@ -84,6 +85,327 @@ using IntTypes = testing::Types; INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueIntTest, IntTypes); +enum LegacyEnum { kValue1, kValue2, kValue3 }; + +enum class EnumClass { kValue4, kValue5, kValue6 }; + +TEST(HashValueTest, EnumAndBool) { + EXPECT_TRUE((is_hashable::value)); + EXPECT_TRUE((is_hashable::value)); + EXPECT_TRUE((is_hashable::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + LegacyEnum::kValue1, LegacyEnum::kValue2, LegacyEnum::kValue3))); + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + EnumClass::kValue4, EnumClass::kValue5, EnumClass::kValue6))); + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(true, false))); +} + +TEST(HashValueTest, FloatingPoint) { + EXPECT_TRUE((is_hashable::value)); + EXPECT_TRUE((is_hashable::value)); + EXPECT_TRUE((is_hashable::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(42.f, 0.f, -0.f, std::numeric_limits::infinity(), + -std::numeric_limits::infinity()))); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(42., 0., -0., std::numeric_limits::infinity(), + -std::numeric_limits::infinity()))); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + // Add some values with small exponent to test that NORMAL values also + // append their category. + .5L, 1.L, 2.L, 4.L, 42.L, 0.L, -0.L, + 17 * static_cast(std::numeric_limits::max()), + std::numeric_limits::infinity(), + -std::numeric_limits::infinity()))); +} + +TEST(HashValueTest, Pointer) { + EXPECT_TRUE((is_hashable::value)); + + int i; + int* ptr = &i; + int* n = nullptr; + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(&i, ptr, nullptr, ptr + 1, n))); +} + +// TODO(EricWF): MSVC 15 has a bug that causes it to incorrectly evaluate the +// SFINAE in internal/hash.h, causing this test to fail. +#if !defined(_MSC_VER) +TEST(HashValueTest, PairAndTuple) { + EXPECT_TRUE((is_hashable>::value)); + EXPECT_TRUE((is_hashable>::value)); + EXPECT_TRUE((is_hashable>::value)); + EXPECT_TRUE((is_hashable>::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + std::make_pair(0, 42), std::make_pair(0, 42), std::make_pair(42, 0), + std::make_pair(0, 0), std::make_pair(42, 42), std::make_pair(1, 42)))); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(std::make_tuple(0, 0, 0), std::make_tuple(0, 0, 42), + std::make_tuple(0, 23, 0), std::make_tuple(17, 0, 0), + std::make_tuple(42, 0, 0), std::make_tuple(3, 9, 9), + std::make_tuple(0, 0, -42)))); + + // Test that tuples of lvalue references work (so we need a few lvalues): + int a = 0, b = 1, c = 17, d = 23; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + std::tie(a, a), std::tie(a, b), std::tie(b, c), std::tie(c, d)))); + + // Test that tuples of rvalue references work: + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + std::forward_as_tuple(0, 0, 0), std::forward_as_tuple(0, 0, 42), + std::forward_as_tuple(0, 23, 0), std::forward_as_tuple(17, 0, 0), + std::forward_as_tuple(42, 0, 0), std::forward_as_tuple(3, 9, 9), + std::forward_as_tuple(0, 0, -42)))); +} +#endif // !defined(_MSC_VER) + +TEST(HashValueTest, CombineContiguousWorks) { + std::vector> v1 = {std::make_tuple(1), std::make_tuple(3)}; + std::vector> v2 = {std::make_tuple(1), std::make_tuple(2)}; + + auto vh1 = SpyHash(v1); + auto vh2 = SpyHash(v2); + EXPECT_NE(vh1, vh2); +} + +struct DummyDeleter { + template + void operator() (T* ptr) {} +}; + +struct SmartPointerEq { + template + bool operator()(const T& t, const U& u) const { + return GetPtr(t) == GetPtr(u); + } + + template + static auto GetPtr(const T& t) -> decltype(&*t) { + return t ? &*t : nullptr; + } + + static std::nullptr_t GetPtr(std::nullptr_t) { return nullptr; } +}; + +TEST(HashValueTest, SmartPointers) { + EXPECT_TRUE((is_hashable>::value)); + EXPECT_TRUE((is_hashable>::value)); + EXPECT_TRUE((is_hashable>::value)); + + int i, j; + std::unique_ptr unique1(&i); + std::unique_ptr unique2(&i); + std::unique_ptr unique_other(&j); + std::unique_ptr unique_null; + + std::shared_ptr shared1(&i, DummyDeleter()); + std::shared_ptr shared2(&i, DummyDeleter()); + std::shared_ptr shared_other(&j, DummyDeleter()); + std::shared_ptr shared_null; + + // Sanity check of the Eq function. + ASSERT_TRUE(SmartPointerEq{}(unique1, shared1)); + ASSERT_FALSE(SmartPointerEq{}(unique1, shared_other)); + ASSERT_TRUE(SmartPointerEq{}(unique_null, nullptr)); + ASSERT_FALSE(SmartPointerEq{}(shared2, nullptr)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::forward_as_tuple(&i, nullptr, // + unique1, unique2, unique_null, // + absl::make_unique(), // + shared1, shared2, shared_null, // + std::make_shared()), + SmartPointerEq{})); +} + +TEST(HashValueTest, FunctionPointer) { + using Func = int (*)(); + EXPECT_TRUE(is_hashable::value); + + Func p1 = [] { return 2; }, p2 = [] { return 1; }; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(p1, p2, nullptr))); +} + +struct WrapInTuple { + template + std::tuple operator()(const T& t) const { + return std::make_tuple(7, t, 0xdeadbeef); + } +}; + +TEST(HashValueTest, Strings) { + EXPECT_TRUE((is_hashable::value)); + EXPECT_TRUE((is_hashable::value)); + + const std::string small = "foo"; + const std::string dup = "foofoo"; + const std::string large = "large"; + const std::string huge = std::string(5000, 'a'); + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + std::string(), absl::string_view(), + std::string(""), absl::string_view(""), + std::string(small), absl::string_view(small), + std::string(dup), absl::string_view(dup), + std::string(large), absl::string_view(large), + std::string(huge), absl::string_view(huge)))); + + // Also check that nested types maintain the same hash. + const WrapInTuple t{}; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + // + t(std::string()), t(absl::string_view()), + t(std::string("")), t(absl::string_view("")), + t(std::string(small)), t(absl::string_view(small)), + t(std::string(dup)), t(absl::string_view(dup)), + t(std::string(large)), t(absl::string_view(large)), + t(std::string(huge)), t(absl::string_view(huge))))); + + // Make sure that hashing a `const char*` does not use its std::string-value. + EXPECT_NE(SpyHash(static_cast("ABC")), + SpyHash(absl::string_view("ABC"))); +} + +// TODO(EricWF): MSVC 15 has a bug that causes it to incorrectly evaluate the +// SFINAE in internal/hash.h, causing this test to fail. +#if !defined(_MSC_VER) +TEST(HashValueTest, StdArray) { + EXPECT_TRUE((is_hashable>::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(std::array{}, std::array{{0, 23, 42}}))); +} +#endif // !defined(_MSC_VER) + +TEST(HashValueTest, StdBitset) { + EXPECT_TRUE((is_hashable>::value)); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + {std::bitset<2>("00"), std::bitset<2>("01"), std::bitset<2>("10"), + std::bitset<2>("11")})); + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + {std::bitset<5>("10101"), std::bitset<5>("10001"), std::bitset<5>()})); + + constexpr int kNumBits = 256; + std::array bit_strings; + bit_strings.fill(std::string(kNumBits, '1')); + bit_strings[1][0] = '0'; + bit_strings[2][1] = '0'; + bit_strings[3][kNumBits / 3] = '0'; + bit_strings[4][kNumBits - 2] = '0'; + bit_strings[5][kNumBits - 1] = '0'; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + {std::bitset(bit_strings[0].c_str()), + std::bitset(bit_strings[1].c_str()), + std::bitset(bit_strings[2].c_str()), + std::bitset(bit_strings[3].c_str()), + std::bitset(bit_strings[4].c_str()), + std::bitset(bit_strings[5].c_str())})); +} // namespace + +template +class HashValueSequenceTest : public testing::Test { +}; +TYPED_TEST_SUITE_P(HashValueSequenceTest); + +TYPED_TEST_P(HashValueSequenceTest, BasicUsage) { + EXPECT_TRUE((is_hashable::value)); + + using ValueType = typename TypeParam::value_type; + auto a = static_cast(0); + auto b = static_cast(23); + auto c = static_cast(42); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(TypeParam(), TypeParam{}, TypeParam{a, b, c}, + TypeParam{a, b}, TypeParam{b, c}))); +} + +REGISTER_TYPED_TEST_CASE_P(HashValueSequenceTest, BasicUsage); +using IntSequenceTypes = + testing::Types, std::forward_list, std::list, + std::vector, std::vector, std::set, + std::multiset>; +INSTANTIATE_TYPED_TEST_CASE_P(My, HashValueSequenceTest, IntSequenceTypes); + +// Private type that only supports AbslHashValue to make sure our chosen hash +// implentation is recursive within absl::Hash. +// It uses std::abs() on the value to provide different bitwise representations +// of the same logical value. +struct Private { + int i; + template + friend H AbslHashValue(H h, Private p) { + return H::combine(std::move(h), std::abs(p.i)); + } + + friend bool operator==(Private a, Private b) { + return std::abs(a.i) == std::abs(b.i); + } + + friend std::ostream& operator<<(std::ostream& o, Private p) { + return o << p.i; + } +}; + +TEST(HashValueTest, PrivateSanity) { + // Sanity check that Private is working as the tests below expect it to work. + EXPECT_TRUE(is_hashable::value); + EXPECT_NE(SpyHash(Private{0}), SpyHash(Private{1})); + EXPECT_EQ(SpyHash(Private{1}), SpyHash(Private{1})); +} + +TEST(HashValueTest, Optional) { + EXPECT_TRUE(is_hashable>::value); + + using O = absl::optional; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + std::make_tuple(O{}, O{{1}}, O{{-1}}, O{{10}}))); +} + +TEST(HashValueTest, Variant) { + using V = absl::variant; + EXPECT_TRUE(is_hashable::value); + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + V(Private{1}), V(Private{-1}), V(Private{2}), V("ABC"), V("BCD")))); + +#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ + struct S {}; + EXPECT_FALSE(is_hashable>::value); +#endif +} + +// TODO(EricWF): MSVC 15 has a bug that causes it to incorrectly evaluate the +// SFINAE in internal/hash.h, causing this test to fail. +#if !defined(_MSC_VER) +TEST(HashValueTest, Maps) { + EXPECT_TRUE((is_hashable>::value)); + + using M = std::map; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + M{}, M{{0, "foo"}}, M{{1, "foo"}}, M{{0, "bar"}}, M{{1, "bar"}}, + M{{0, "foo"}, {42, "bar"}}, M{{1, "foo"}, {42, "bar"}}, + M{{1, "foo"}, {43, "bar"}}, M{{1, "foo"}, {43, "baz"}}))); + + using MM = std::multimap; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( + MM{}, MM{{0, "foo"}}, MM{{1, "foo"}}, MM{{0, "bar"}}, MM{{1, "bar"}}, + MM{{0, "foo"}, {0, "bar"}}, MM{{0, "bar"}, {0, "foo"}}, + MM{{0, "foo"}, {42, "bar"}}, MM{{1, "foo"}, {42, "bar"}}, + MM{{1, "foo"}, {1, "foo"}, {43, "bar"}}, MM{{1, "foo"}, {43, "baz"}}))); +} +#endif // !defined(_MSC_VER) + template struct IsHashCallble : std::false_type {}; @@ -108,7 +430,8 @@ TEST(IsHashableTest, ValidHash) { EXPECT_TRUE(IsHashCallble::value); EXPECT_TRUE(IsAggregateInitializable>::value); } -#if ABSL_HASH_INTERNAL_CAN_POISON_ && !defined(__APPLE__) + +#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ TEST(IsHashableTest, PoisonHash) { struct X {}; EXPECT_FALSE((is_hashable::value)); @@ -120,7 +443,7 @@ TEST(IsHashableTest, PoisonHash) { EXPECT_FALSE(IsHashCallble::value); EXPECT_FALSE(IsAggregateInitializable>::value); } -#endif // ABSL_HASH_INTERNAL_CAN_POISON_ +#endif // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ // Hashable types // @@ -245,13 +568,13 @@ void TestCustomHashType(InvokeTagConstant, T...) { } void TestCustomHashType(InvokeTagConstant) { -#if ABSL_HASH_INTERNAL_CAN_POISON_ +#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ // is_hashable is false if we don't support any of the hooks. using type = CustomHashType<>; EXPECT_FALSE(is_hashable()); EXPECT_FALSE(is_hashable()); EXPECT_FALSE(is_hashable()); -#endif // ABSL_HASH_INTERNAL_CAN_POISON_ +#endif // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ } template diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 6c00f354..ba6d7468 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -541,17 +541,8 @@ hash_range_or_bytes(H hash_state, const T* data, size_t size) { // * If is_uniquely_represented, hash bytes directly. // * ADL AbslHashValue(H, const T&) call. // * std::hash - -// In MSVC we can't probe std::hash or stdext::hash because it triggers a -// static_assert instead of failing substitution. -#if defined(_MSC_VER) -#define ABSL_HASH_INTERNAL_CAN_POISON_ 0 -#else // _MSC_VER -#define ABSL_HASH_INTERNAL_CAN_POISON_ 1 -#endif // _MSC_VER - #if defined(ABSL_INTERNAL_LEGACY_HASH_NAMESPACE) && \ - ABSL_HASH_INTERNAL_CAN_POISON_ + ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 1 #else #define ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ 0 @@ -616,13 +607,7 @@ struct HashSelect { #endif // ABSL_HASH_INTERNAL_SUPPORT_LEGACY_HASH_ template - using ProbeStdHash = -#if ABSL_HASH_INTERNAL_CAN_POISON_ - std::is_convertible()(std::declval())), - size_t>; -#else // ABSL_HASH_INTERNAL_CAN_POISON_ - std::true_type; -#endif // ABSL_HASH_INTERNAL_CAN_POISON_ + using ProbeStdHash = absl::type_traits_internal::IsHashable; template using ProbeNone = std::true_type; diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h index 03d795b0..e7d1dfef 100644 --- a/absl/hash/internal/spy_hash_state.h +++ b/absl/hash/internal/spy_hash_state.h @@ -200,7 +200,7 @@ bool RunOnStartup::run = (f(), true); template < typename T, typename U, // Only trigger for when (T != U), - absl::enable_if_t::value, int> = 0, + typename = absl::enable_if_t::value>, // This statement works in two ways: // - First, it instantiates RunOnStartup and forces the initialization of // `run`, which set the global variable. diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 23ebd6ed..88853974 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -413,21 +413,73 @@ template using result_of_t = typename std::result_of::type; namespace type_traits_internal { +// In MSVC we can't probe std::hash or stdext::hash because it triggers a +// static_assert instead of failing substitution. Libc++ prior to 4.0 +// also used a static_assert. +// +#if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \ + _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11) +#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 0 +#else +#define ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ 1 +#endif + +#if !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ template +struct IsHashable : std::true_type {}; +#else // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ +template struct IsHashable : std::false_type {}; template -struct IsHashable>()(std::declval()))> - : std::true_type {}; +struct IsHashable< + Key, + absl::enable_if_t&>()(std::declval())), + std::size_t>::value>> : std::true_type {}; +#endif // !ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ + +struct AssertHashEnabledHelper { + private: + static void Sink(...) {} + struct NAT {}; + + template + static auto GetReturnType(int) + -> decltype(std::declval>()(std::declval())); + template + static NAT GetReturnType(...); + + template + static std::nullptr_t DoIt() { + static_assert(IsHashable::value, + "std::hash does not provide a call operator"); + static_assert( + std::is_default_constructible>::value, + "std::hash must be default constructible when it is enabled"); + static_assert( + std::is_copy_constructible>::value, + "std::hash must be copy constructible when it is enabled"); + static_assert(absl::is_copy_assignable>::value, + "std::hash must be copy assignable when it is enabled"); + // is_destructible is unchecked as it's implied by each of the + // is_constructible checks. + using ReturnType = decltype(GetReturnType(0)); + static_assert(std::is_same::value || + std::is_same::value, + "std::hash must return size_t"); + return nullptr; + } + + template + friend void AssertHashEnabled(); +}; -template -struct IsHashEnabled - : absl::conjunction>, - std::is_copy_constructible>, - std::is_destructible>, - absl::is_copy_assignable>, - IsHashable> {}; +template +inline void AssertHashEnabled() { + using Helper = AssertHashEnabledHelper; + Helper::Sink(Helper::DoIt()...); +} } // namespace type_traits_internal 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 3dca822c..2e49e48c 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -1021,7 +1021,7 @@ TEST(MakeTime, LocalTimeLibC) { // 1) we know how to change the time zone used by localtime()/mktime(), // 2) cctz and localtime()/mktime() will use similar-enough tzdata, and // 3) we have some idea about how mktime() behaves during transitions. -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) const char* const ep = getenv("TZ"); std::string tz_name = (ep != nullptr) ? ep : ""; for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index 477e5895..a0ab1e8f 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -1605,11 +1605,12 @@ struct VariantHashVisitor { template struct VariantHashBase...>::value>, + type_traits_internal::IsHashable...>::value>, Ts...> { using argument_type = Variant; using result_type = size_t; size_t operator()(const Variant& var) const { + type_traits_internal::AssertHashEnabled(); if (var.valueless_by_exception()) { return 239799884; } diff --git a/absl/types/optional.h b/absl/types/optional.h index 7677fe52..fd185f35 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -467,6 +467,7 @@ struct optional_hash_base >()( using argument_type = absl::optional; using result_type = size_t; size_t operator()(const absl::optional& opt) const { + absl::type_traits_internal::AssertHashEnabled>(); if (opt) { return std::hash >()(*opt); } else { diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index fc4f00a4..bedf5b0e 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -1504,18 +1504,19 @@ TEST(optionalTest, Hash) { static_assert(is_hash_enabled_for>::value, ""); static_assert(is_hash_enabled_for>::value, ""); + static_assert( + absl::type_traits_internal::IsHashable>::value, ""); + static_assert( + absl::type_traits_internal::IsHashable>::value, + ""); + absl::type_traits_internal::AssertHashEnabled>(); + absl::type_traits_internal::AssertHashEnabled>(); -#if defined(_MSC_VER) || (defined(_LIBCPP_VERSION) && \ - _LIBCPP_VERSION < 4000 && _LIBCPP_STD_VER > 11) - // For MSVC and libc++ (< 4.0 and c++14), std::hash primary template has a - // static_assert to catch any user-defined type that doesn't provide a hash - // specialization. So instantiating std::hash> will result - // in a hard error which is not SFINAE friendly. -#define ABSL_STD_HASH_NOT_SFINAE_FRIENDLY 1 -#endif - -#ifndef ABSL_STD_HASH_NOT_SFINAE_FRIENDLY +#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ static_assert(!is_hash_enabled_for>::value, ""); + static_assert(!absl::type_traits_internal::IsHashable< + absl::optional>::value, + ""); #endif // libstdc++ std::optional is missing remove_const_t, i.e. it's using diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index 80e8467e..463d775a 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -1977,29 +1977,17 @@ TEST(VariantTest, MonostateHash) { } TEST(VariantTest, Hash) { - static_assert(type_traits_internal::IsHashEnabled>::value, ""); - static_assert(type_traits_internal::IsHashEnabled>::value, + static_assert(type_traits_internal::IsHashable>::value, ""); + static_assert(type_traits_internal::IsHashable>::value, ""); + static_assert(type_traits_internal::IsHashable>::value, ""); - static_assert( - type_traits_internal::IsHashEnabled>::value, ""); - -#if defined(_MSC_VER) || \ - (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 4000 && \ - _LIBCPP_STD_VER > 11) || \ - defined(__APPLE__) - // For MSVC and libc++ (< 4.0 and c++14), std::hash primary template has a - // static_assert to catch any user-defined type T that doesn't provide a hash - // specialization. So instantiating std::hash> will result - // in a hard error which is not SFINAE friendly. -#define ABSL_STD_HASH_NOT_SFINAE_FRIENDLY 1 -#endif -#ifndef ABSL_STD_HASH_NOT_SFINAE_FRIENDLY - static_assert( - !type_traits_internal::IsHashEnabled>::value, ""); - static_assert(!type_traits_internal::IsHashEnabled< - variant>::value, +#if ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_ + static_assert(!type_traits_internal::IsHashable>::value, ""); + static_assert( + !type_traits_internal::IsHashable>::value, + ""); #endif // MSVC std::hash does not use the index, thus produce the same @@ -2023,11 +2011,10 @@ TEST(VariantTest, Hash) { EXPECT_GT(hashcodes.size(), 90); // test const-qualified + static_assert(type_traits_internal::IsHashable>::value, + ""); static_assert( - type_traits_internal::IsHashEnabled>::value, ""); - static_assert( - type_traits_internal::IsHashEnabled>::value, - ""); + type_traits_internal::IsHashable>::value, ""); std::hash> c_hash; for (int i = 0; i < 100; ++i) { EXPECT_EQ(hash(i), c_hash(i)); -- cgit v1.2.3 From 2901ec32a919311384d6ad4194e2d927c06831f7 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 7 Feb 2019 14:13:06 -0800 Subject: Export of internal Abseil changes. -- 5da9755667df37e38ccaf6938c9f408e294110bb by Shaindel Schwartz : Import of CCTZ from GitHub. PiperOrigin-RevId: 232942734 -- b6fb275769c66fdd2bd92b119198c59e9a7dd737 by Samuel Benzaquen : Fix integral underflow when from-arg width is INT_MIN. PiperOrigin-RevId: 232888037 -- 4135dbba4a26c4642277fc2a7e2a833d593daa1c by Abseil Team : Add the insert_return_type alias to raw_hash_set. PiperOrigin-RevId: 232683892 -- 0b120b7d3693800bbb886f6fc607ae54a9338cb1 by Abseil Team : Macros to detect and disabled SafeStack https://clang.llvm.org/docs/SafeStack.html PiperOrigin-RevId: 232680114 -- a77b3fb533a9e37966d1d6ef5ccd09c73fff2ca1 by Abseil Team : Avoid potential red zone clobber Pushing on the stack on x86-64 may clobber local variables held below %rsp in the red zone. Avoid this by using lea on x86-64. PiperOrigin-RevId: 232592478 -- bf326a0eefa92f4e704287563df0c5a5b1873b6d by Eric Fiselier : Add additional tests for AbslHashValue. PiperOrigin-RevId: 232344325 -- 816e4f98fd7632c944c779db87b7dac4e138afcf by Eric Fiselier : Avoid upcoming GCC 9.0 warnings about base class init. Currently, in trunk, GCC has a new warning under -Wextra that diagnoses when a derived class fails to explicitly initialize the base class in a constructor initializer list. This patch avoids this warning. PiperOrigin-RevId: 232327626 -- 779c0f44b3c2b7a04d4bdf978641eb8180515bf6 by Eric Fiselier : Guard against C++2a char8_t change. PiperOrigin-RevId: 232326178 -- 41e5395b85bbbfb5bf418cc21b04ad4ccb15a284 by Eric Fiselier : Avoid Clang Warning PiperOrigin-RevId: 232138866 GitOrigin-RevId: 5da9755667df37e38ccaf6938c9f408e294110bb Change-Id: I49ee4f58db177b81b039d7d949f671c97c5a7933 --- absl/base/attributes.h | 11 ++ absl/container/BUILD.bazel | 2 +- absl/container/fixed_array_test.cc | 17 +++ absl/container/inlined_vector_test.cc | 19 ++++ absl/container/internal/common.h | 136 +++++++++++++++++++++++- absl/container/internal/hashtablez_sampler.cc | 2 +- absl/container/internal/hashtablez_sampler.h | 12 +-- absl/container/internal/raw_hash_set.h | 136 ++---------------------- absl/container/internal/raw_hash_set_test.cc | 2 +- absl/debugging/symbolize_test.cc | 12 ++- absl/numeric/int128_test.cc | 25 +++++ absl/strings/internal/str_format/bind.cc | 3 +- absl/strings/internal/str_format/bind_test.cc | 15 +++ absl/strings/internal/utf8_test.cc | 9 ++ absl/strings/str_split_test.cc | 9 ++ absl/time/internal/cctz/src/zone_info_source.cc | 2 +- absl/types/optional.h | 5 +- absl/types/span_test.cc | 15 +++ 18 files changed, 287 insertions(+), 145 deletions(-) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/attributes.h b/absl/base/attributes.h index 291ad89e..fa44012e 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -287,6 +287,17 @@ #define ABSL_ATTRIBUTE_NO_SANITIZE_CFI #endif +// ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK +// +// Tells the SafeStack to not instrument a given function. +// See https://clang.llvm.org/docs/SafeStack.html for details. +#if defined(__GNUC__) && defined(SAFESTACK_SANITIZER) +#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \ + __attribute__((no_sanitize("safe-stack"))) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK +#endif + // ABSL_ATTRIBUTE_RETURNS_NONNULL // // Tells the compiler that a particular function never returns a null pointer. diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index acdbc473..f3b3a2c0 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -542,6 +542,7 @@ cc_library( copts = ABSL_DEFAULT_COPTS, deps = [ "//absl/meta:type_traits", + "//absl/types:optional", ], ) @@ -565,7 +566,6 @@ cc_library( "//absl/base:endian", "//absl/memory", "//absl/meta:type_traits", - "//absl/types:optional", "//absl/utility", ], ) diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc index 205ff41f..1679ba4f 100644 --- a/absl/container/fixed_array_test.cc +++ b/absl/container/fixed_array_test.cc @@ -869,4 +869,21 @@ TEST(FixedArrayTest, AddressSanitizerAnnotations4) { } #endif // ADDRESS_SANITIZER +TEST(FixedArrayTest, AbslHashValueWorks) { + using V = absl::FixedArray; + std::vector cases; + + // Generate a variety of vectors some of these are small enough for the inline + // space but are stored out of line. + for (int i = 0; i < 10; ++i) { + V v(i); + for (int j = 0; j < i; ++j) { + v[j] = j; + } + cases.push_back(v); + } + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(cases)); +} + } // namespace diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 9408ee9d..5b1527e9 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -1762,4 +1762,23 @@ TEST(AllocatorSupportTest, SizeAllocConstructor) { } } +TEST(InlinedVectorTest, AbslHashValueWorks) { + using V = absl::InlinedVector; + std::vector cases; + + // Generate a variety of vectors some of these are small enough for the inline + // space but are stored out of line. + for (int i = 0; i < 10; ++i) { + V v; + for (int j = 0; j < i; ++j) { + v.push_back(j); + } + cases.push_back(v); + v.resize(i % 4); + cases.push_back(v); + } + + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(cases)); +} + } // anonymous namespace diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h index a6dc9103..c7816566 100644 --- a/absl/container/internal/common.h +++ b/absl/container/internal/common.h @@ -18,6 +18,7 @@ #include #include "absl/meta/type_traits.h" +#include "absl/types/optional.h" namespace absl { namespace container_internal { @@ -42,7 +43,140 @@ struct KeyArg { using type = key_type; }; +// The node_handle concept from C++17. +// We specialize node_handle for sets and maps. node_handle_base holds the +// common API of both. +template +class node_handle_base { + protected: + using slot_type = typename PolicyTraits::slot_type; + + public: + using allocator_type = Alloc; + + constexpr node_handle_base() {} + node_handle_base(node_handle_base&& other) noexcept { + *this = std::move(other); + } + ~node_handle_base() { destroy(); } + node_handle_base& operator=(node_handle_base&& other) noexcept { + destroy(); + if (!other.empty()) { + alloc_ = other.alloc_; + PolicyTraits::transfer(alloc(), slot(), other.slot()); + other.reset(); + } + return *this; + } + + bool empty() const noexcept { return !alloc_; } + explicit operator bool() const noexcept { return !empty(); } + allocator_type get_allocator() const { return *alloc_; } + + protected: + friend struct CommonAccess; + + node_handle_base(const allocator_type& a, slot_type* s) : alloc_(a) { + PolicyTraits::transfer(alloc(), slot(), s); + } + + void destroy() { + if (!empty()) { + PolicyTraits::destroy(alloc(), slot()); + reset(); + } + } + + void reset() { + assert(alloc_.has_value()); + alloc_ = absl::nullopt; + } + + slot_type* slot() const { + assert(!empty()); + return reinterpret_cast(std::addressof(slot_space_)); + } + allocator_type* alloc() { return std::addressof(*alloc_); } + + private: + absl::optional alloc_; + mutable absl::aligned_storage_t + slot_space_; +}; + +// For sets. +template +class node_handle : public node_handle_base { + using Base = typename node_handle::node_handle_base; + + public: + using value_type = typename PolicyTraits::value_type; + + constexpr node_handle() {} + + value_type& value() const { return PolicyTraits::element(this->slot()); } + + private: + friend struct CommonAccess; + + node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {} +}; + +// For maps. +template +class node_handle> + : public node_handle_base { + using Base = typename node_handle::node_handle_base; + + public: + using key_type = typename Policy::key_type; + using mapped_type = typename Policy::mapped_type; + + constexpr node_handle() {} + + auto key() const -> decltype(PolicyTraits::key(this->slot())) { + return PolicyTraits::key(this->slot()); + } + + mapped_type& mapped() const { + return PolicyTraits::value(&PolicyTraits::element(this->slot())); + } + + private: + friend struct CommonAccess; + + node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {} +}; + +// Provide access to non-public node-handle functions. +struct CommonAccess { + template + static auto GetSlot(const Node& node) -> decltype(node.slot()) { + return node.slot(); + } + + template + static void Reset(Node* node) { + node->reset(); + } + + template + static T Make(Args&&... args) { + return T(std::forward(args)...); + } +}; + +// Implement the insert_return_type<> concept of C++17. +template +struct InsertReturnType { + Iterator position; + bool inserted; + NodeType node; +}; + } // namespace container_internal -} // namespace absl +} // namespace absl #endif // ABSL_CONTAINER_INTERNAL_CONTAINER_H_ diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 99cd8344..dc669248 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -254,7 +254,7 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { } #if ABSL_PER_THREAD_TLS == 1 -ABSL_PER_THREAD_TLS_KEYWORD int64_t next_sample = 0; +ABSL_PER_THREAD_TLS_KEYWORD int64_t global_next_sample = 0; #endif // ABSL_PER_THREAD_TLS == 1 void UnsampleSlow(HashtablezInfo* info) { diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 126a0ade..8b81653a 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -146,23 +146,23 @@ class HashtablezInfoHandle { HashtablezInfo* info_; }; -// Returns an RAII sampling handle that manages registration and unregistation -// with the global sampler. #if ABSL_PER_THREAD_TLS == 1 -extern ABSL_PER_THREAD_TLS_KEYWORD int64_t next_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 == 0 static auto* mu = new absl::Mutex; - static int64_t next_sample = 0; + static int64_t global_next_sample = 0; absl::MutexLock l(mu); #endif // !ABSL_HAVE_THREAD_LOCAL - if (ABSL_PREDICT_TRUE(--next_sample > 0)) { + if (ABSL_PREDICT_TRUE(--global_next_sample > 0)) { return HashtablezInfoHandle(nullptr); } - return HashtablezInfoHandle(SampleSlow(&next_sample)); + return HashtablezInfoHandle(SampleSlow(&global_next_sample)); } // Holds samples and their associated stack traces with a soft limit of diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 8e3fa02d..a5d0cae0 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -115,7 +115,6 @@ #include "absl/container/internal/layout.h" #include "absl/memory/memory.h" #include "absl/meta/type_traits.h" -#include "absl/types/optional.h" #include "absl/utility/utility.h" namespace absl { @@ -502,126 +501,6 @@ inline size_t GrowthToLowerboundCapacity(size_t growth) { return growth + static_cast((static_cast(growth) - 1) / 7); } -// The node_handle concept from C++17. -// We specialize node_handle for sets and maps. node_handle_base holds the -// common API of both. -template -class node_handle_base { - protected: - using PolicyTraits = hash_policy_traits; - using slot_type = typename PolicyTraits::slot_type; - - public: - using allocator_type = Alloc; - - constexpr node_handle_base() {} - node_handle_base(node_handle_base&& other) noexcept { - *this = std::move(other); - } - ~node_handle_base() { destroy(); } - node_handle_base& operator=(node_handle_base&& other) { - destroy(); - if (!other.empty()) { - alloc_ = other.alloc_; - PolicyTraits::transfer(alloc(), slot(), other.slot()); - other.reset(); - } - return *this; - } - - bool empty() const noexcept { return !alloc_; } - explicit operator bool() const noexcept { return !empty(); } - allocator_type get_allocator() const { return *alloc_; } - - protected: - template - friend class raw_hash_set; - - node_handle_base(const allocator_type& a, slot_type* s) : alloc_(a) { - PolicyTraits::transfer(alloc(), slot(), s); - } - - void destroy() { - if (!empty()) { - PolicyTraits::destroy(alloc(), slot()); - reset(); - } - } - - void reset() { - assert(alloc_.has_value()); - alloc_ = absl::nullopt; - } - - slot_type* slot() const { - assert(!empty()); - return reinterpret_cast(std::addressof(slot_space_)); - } - allocator_type* alloc() { return std::addressof(*alloc_); } - - private: - absl::optional alloc_; - mutable absl::aligned_storage_t - slot_space_; -}; - -// For sets. -template -class node_handle : public node_handle_base { - using Base = typename node_handle::node_handle_base; - - public: - using value_type = typename Base::PolicyTraits::value_type; - - constexpr node_handle() {} - - value_type& value() const { - return Base::PolicyTraits::element(this->slot()); - } - - private: - template - friend class raw_hash_set; - - node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {} -}; - -// For maps. -template -class node_handle> - : public node_handle_base { - using Base = typename node_handle::node_handle_base; - - public: - using key_type = typename Policy::key_type; - using mapped_type = typename Policy::mapped_type; - - constexpr node_handle() {} - - auto key() const -> decltype(Base::PolicyTraits::key(this->slot())) { - return Base::PolicyTraits::key(this->slot()); - } - - mapped_type& mapped() const { - return Base::PolicyTraits::value( - &Base::PolicyTraits::element(this->slot())); - } - - private: - template - friend class raw_hash_set; - - node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {} -}; - -// Implement the insert_return_type<> concept of C++17. -template -struct insert_return_type { - Iterator position; - bool inserted; - NodeType node; -}; - // Policy: a policy defines how to perform different operations on // the slots of the hashtable (see hash_policy_traits.h for the full interface // of policy). @@ -828,7 +707,8 @@ class raw_hash_set { iterator inner_; }; - using node_type = container_internal::node_handle; + using node_type = node_handle, Alloc>; + using insert_return_type = InsertReturnType; raw_hash_set() noexcept( std::is_nothrow_default_constructible::value&& @@ -1136,13 +1016,14 @@ class raw_hash_set { insert(ilist.begin(), ilist.end()); } - insert_return_type insert(node_type&& node) { + insert_return_type insert(node_type&& node) { if (!node) return {end(), false, node_type()}; - const auto& elem = PolicyTraits::element(node.slot()); + const auto& elem = PolicyTraits::element(CommonAccess::GetSlot(node)); auto res = PolicyTraits::apply( - InsertSlot{*this, std::move(*node.slot())}, elem); + InsertSlot{*this, std::move(*CommonAccess::GetSlot(node))}, + elem); if (res.second) { - node.reset(); + CommonAccess::Reset(&node); return {res.first, true, node_type()}; } else { return {res.first, false, std::move(node)}; @@ -1306,7 +1187,8 @@ class raw_hash_set { } node_type extract(const_iterator position) { - node_type node(alloc_ref(), position.inner_.slot_); + auto node = + CommonAccess::Make(alloc_ref(), position.inner_.slot_); erase_meta_only(position); return node; } diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index d9f1826a..7adcc96d 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -1706,7 +1706,7 @@ TEST(Nodes, ExtractInsert) { EXPECT_FALSE(node.empty()); StringTable t2; - auto res = t2.insert(std::move(node)); + StringTable::insert_return_type res = t2.insert(std::move(node)); EXPECT_TRUE(res.inserted); EXPECT_THAT(*res.position, Pair(k0, "")); EXPECT_FALSE(res.node); diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index 8029fbe9..dcb52695 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -392,16 +392,20 @@ TEST(Symbolize, ForEachSection) { extern "C" { inline void *ABSL_ATTRIBUTE_ALWAYS_INLINE inline_func() { void *pc = nullptr; -#if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); +#if defined(__i386__) + __asm__ __volatile__("call 1f;\n 1: pop %[PC]" : [ PC ] "=r"(pc)); +#elif defined(__x86_64__) + __asm__ __volatile__("leaq 0(%%rip),%[PC];\n" : [ PC ] "=r"(pc)); #endif return pc; } void *ABSL_ATTRIBUTE_NOINLINE non_inline_func() { void *pc = nullptr; -#if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); +#if defined(__i386__) + __asm__ __volatile__("call 1f;\n 1: pop %[PC]" : [ PC ] "=r"(pc)); +#elif defined(__x86_64__) + __asm__ __volatile__("leaq 0(%%rip),%[PC];\n" : [ PC ] "=r"(pc)); #endif return pc; } diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc index 81c868d7..4a6eb455 100644 --- a/absl/numeric/int128_test.cc +++ b/absl/numeric/int128_test.cc @@ -440,4 +440,29 @@ TEST(Uint128, NumericLimitsTest) { EXPECT_EQ(absl::Uint128Max(), std::numeric_limits::max()); } +TEST(Uint128, Hash) { + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({ + // Some simple values + absl::uint128{0}, + absl::uint128{1}, + ~absl::uint128{}, + // 64 bit limits + absl::uint128{std::numeric_limits::max()}, + absl::uint128{std::numeric_limits::max()} + 0, + absl::uint128{std::numeric_limits::max()} + 1, + absl::uint128{std::numeric_limits::max()} + 2, + // Keeping high same + absl::uint128{1} << 62, + absl::uint128{1} << 63, + // Keeping low same + absl::uint128{1} << 64, + absl::uint128{1} << 65, + // 128 bit limits + std::numeric_limits::max(), + std::numeric_limits::max() - 1, + std::numeric_limits::min() + 1, + std::numeric_limits::min(), + })); +} + } // namespace diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc index 758adb7a..a89295d5 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc @@ -53,7 +53,8 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound, // "A negative field width is taken as a '-' flag followed by a // positive field width." force_left = true; - width = -width; + // Make sure we don't overflow the width when negating it. + width = -std::max(width, -std::numeric_limits::max()); } } diff --git a/absl/strings/internal/str_format/bind_test.cc b/absl/strings/internal/str_format/bind_test.cc index 47575739..ba6470ec 100644 --- a/absl/strings/internal/str_format/bind_test.cc +++ b/absl/strings/internal/str_format/bind_test.cc @@ -1,6 +1,7 @@ #include "absl/strings/internal/str_format/bind.h" #include +#include #include "gtest/gtest.h" @@ -91,6 +92,20 @@ TEST_F(FormatBindTest, BindSingle) { } } +TEST_F(FormatBindTest, WidthUnderflowRegression) { + UnboundConversion props; + BoundConversion bound; + int next = 0; + const int args_i[] = {std::numeric_limits::min(), 17}; + const FormatArgImpl args[] = {FormatArgImpl(args_i[0]), + FormatArgImpl(args_i[1])}; + ASSERT_TRUE(Extract("*d", &props, &next)); + ASSERT_TRUE(BindWithPack(&props, args, &bound)); + + EXPECT_EQ(bound.width(), std::numeric_limits::max()); + EXPECT_EQ(bound.arg(), args + 1); +} + TEST_F(FormatBindTest, FormatPack) { struct Expectation { int line; diff --git a/absl/strings/internal/utf8_test.cc b/absl/strings/internal/utf8_test.cc index 64cec70d..07a000cb 100644 --- a/absl/strings/internal/utf8_test.cc +++ b/absl/strings/internal/utf8_test.cc @@ -22,6 +22,11 @@ namespace { +#if !defined(__cpp_char8_t) +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++2a-compat" +#endif TEST(EncodeUTF8Char, BasicFunction) { std::pair tests[] = {{0x0030, u8"\u0030"}, {0x00A3, u8"\u00A3"}, @@ -53,5 +58,9 @@ TEST(EncodeUTF8Char, BasicFunction) { EXPECT_LE(absl::strings_internal::EncodeUTF8Char(buf2, -1), absl::strings_internal::kMaxEncodedUTF8Size); } +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +#endif // !defined(__cpp_char8_t) } // namespace diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc index caa88277..a0085582 100644 --- a/absl/strings/str_split_test.cc +++ b/absl/strings/str_split_test.cc @@ -647,6 +647,11 @@ TEST(Split, StringDelimiter) { } } +#if !defined(__cpp_char8_t) +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++2a-compat" +#endif TEST(Split, UTF8) { // Tests splitting utf8 strings and utf8 delimiters. std::string utf8_string = u8"\u03BA\u1F79\u03C3\u03BC\u03B5"; @@ -673,6 +678,10 @@ TEST(Split, UTF8) { EXPECT_THAT(v, ElementsAre("Foo", u8"h\u00E4llo", u8"th\u4E1Ere")); } } +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +#endif // !defined(__cpp_char8_t) TEST(Split, EmptyStringDelimiter) { { diff --git a/absl/time/internal/cctz/src/zone_info_source.cc b/absl/time/internal/cctz/src/zone_info_source.cc index bf2d2d2d..1bc16aec 100644 --- a/absl/time/internal/cctz/src/zone_info_source.cc +++ b/absl/time/internal/cctz/src/zone_info_source.cc @@ -54,7 +54,7 @@ ZoneInfoSourceFactory default_factory = DefaultFactory; #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZA=?default_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZA") -#elif defined(_M_IA_64) || defined(_M_AMD64) +#elif defined(_M_IA_64) || defined(_M_AMD64) || defined(_M_ARM64) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA=?default_factory@cctz_extension@time_internal@absl@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@5@@ZEA") diff --git a/absl/types/optional.h b/absl/types/optional.h index fd185f35..d800ca68 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -295,7 +295,7 @@ class optional_data : public optional_data_base { optional_data() = default; - optional_data(const optional_data& rhs) { + optional_data(const optional_data& rhs) : optional_data_base() { if (rhs.engaged_) { this->construct(rhs.data_); } @@ -303,7 +303,8 @@ class optional_data : public optional_data_base { optional_data(optional_data&& rhs) noexcept( absl::default_allocator_is_nothrow::value || - std::is_nothrow_move_constructible::value) { + std::is_nothrow_move_constructible::value) + : optional_data_base() { if (rhs.engaged_) { this->construct(std::move(rhs.data_)); } diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc index bd739ff2..f4203b52 100644 --- a/absl/types/span_test.cc +++ b/absl/types/span_test.cc @@ -779,4 +779,19 @@ TEST(Span, SpanSize) { EXPECT_LE(sizeof(absl::Span), 2 * sizeof(void*)); } +TEST(Span, Hash) { + int array[] = {1, 2, 3, 4}; + int array2[] = {1, 2, 3}; + using T = absl::Span; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly( + {// Empties + T(), T(nullptr, 0), T(array, 0), T(array2, 0), + // Different array with same value + T(array, 3), T(array2), T({1, 2, 3}), + // Same array, but different length + T(array, 1), T(array, 2), + // Same length, but different array + T(array + 1, 2), T(array + 2, 2)})); +} + } // namespace -- cgit v1.2.3 From 38b704384cd2f17590b3922b97744be0b43622c9 Mon Sep 17 00:00:00 2001 From: nik7273 Date: Fri, 8 Mar 2019 10:27:53 -0500 Subject: Changed HTTP URLs to HTTPS where possible (#270) --- CMake/AbseilHelpers.cmake | 2 +- CMake/README.md | 2 +- CMakeLists.txt | 2 +- LICENSE | 4 ++-- README.md | 8 ++++---- absl/BUILD.bazel | 2 +- absl/CMakeLists.txt | 2 +- absl/algorithm/BUILD.bazel | 2 +- absl/algorithm/CMakeLists.txt | 2 +- absl/algorithm/algorithm.h | 4 ++-- absl/algorithm/algorithm_test.cc | 2 +- absl/algorithm/container.h | 2 +- absl/algorithm/container_test.cc | 2 +- absl/algorithm/equal_benchmark.cc | 2 +- absl/base/BUILD.bazel | 2 +- absl/base/CMakeLists.txt | 2 +- absl/base/attributes.h | 2 +- absl/base/bit_cast_test.cc | 2 +- absl/base/call_once.h | 2 +- absl/base/call_once_test.cc | 2 +- absl/base/casts.h | 2 +- absl/base/config.h | 2 +- absl/base/config_test.cc | 2 +- absl/base/const_init.h | 2 +- absl/base/dynamic_annotations.cc | 2 +- absl/base/dynamic_annotations.h | 2 +- absl/base/exception_safety_testing_test.cc | 2 +- absl/base/inline_variable_test.cc | 2 +- absl/base/inline_variable_test_a.cc | 2 +- absl/base/inline_variable_test_b.cc | 2 +- absl/base/internal/atomic_hook.h | 2 +- absl/base/internal/atomic_hook_test.cc | 2 +- absl/base/internal/bits.h | 2 +- absl/base/internal/bits_test.cc | 2 +- absl/base/internal/cycleclock.cc | 2 +- absl/base/internal/cycleclock.h | 2 +- absl/base/internal/direct_mmap.h | 2 +- absl/base/internal/endian.h | 2 +- absl/base/internal/endian_test.cc | 2 +- absl/base/internal/exception_safety_testing.cc | 2 +- absl/base/internal/exception_safety_testing.h | 6 +++--- absl/base/internal/exception_testing.h | 2 +- absl/base/internal/hide_ptr.h | 2 +- absl/base/internal/identity.h | 2 +- absl/base/internal/inline_variable.h | 2 +- absl/base/internal/inline_variable_testing.h | 2 +- absl/base/internal/invoke.h | 2 +- absl/base/internal/low_level_alloc.cc | 2 +- absl/base/internal/low_level_alloc.h | 2 +- absl/base/internal/low_level_alloc_test.cc | 2 +- absl/base/internal/low_level_scheduling.h | 2 +- absl/base/internal/per_thread_tls.h | 2 +- absl/base/internal/pretty_function.h | 2 +- absl/base/internal/raw_logging.cc | 2 +- absl/base/internal/raw_logging.h | 2 +- absl/base/internal/scheduling_mode.h | 2 +- absl/base/internal/spinlock.cc | 2 +- absl/base/internal/spinlock.h | 2 +- absl/base/internal/spinlock_akaros.inc | 2 +- absl/base/internal/spinlock_benchmark.cc | 2 +- absl/base/internal/spinlock_linux.inc | 2 +- absl/base/internal/spinlock_posix.inc | 2 +- absl/base/internal/spinlock_wait.cc | 2 +- absl/base/internal/spinlock_wait.h | 2 +- absl/base/internal/spinlock_win32.inc | 2 +- absl/base/internal/sysinfo.cc | 2 +- absl/base/internal/sysinfo.h | 2 +- absl/base/internal/sysinfo_test.cc | 2 +- absl/base/internal/thread_identity.cc | 2 +- absl/base/internal/thread_identity.h | 2 +- absl/base/internal/thread_identity_benchmark.cc | 2 +- absl/base/internal/thread_identity_test.cc | 2 +- absl/base/internal/throw_delegate.cc | 2 +- absl/base/internal/throw_delegate.h | 2 +- absl/base/internal/tsan_mutex_interface.h | 2 +- absl/base/internal/unaligned_access.h | 2 +- absl/base/internal/unscaledcycleclock.cc | 2 +- absl/base/internal/unscaledcycleclock.h | 2 +- absl/base/invoke_test.cc | 2 +- absl/base/log_severity.h | 2 +- absl/base/macros.h | 2 +- absl/base/optimization.h | 2 +- absl/base/policy_checks.h | 2 +- absl/base/port.h | 2 +- absl/base/raw_logging_test.cc | 2 +- absl/base/spinlock_test_common.cc | 2 +- absl/base/thread_annotations.h | 2 +- absl/base/throw_delegate_test.cc | 2 +- absl/compiler_config_setting.bzl | 2 +- absl/container/BUILD.bazel | 2 +- absl/container/CMakeLists.txt | 2 +- absl/container/fixed_array.h | 2 +- absl/container/fixed_array_benchmark.cc | 2 +- absl/container/fixed_array_exception_safety_test.cc | 2 +- absl/container/fixed_array_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/inlined_vector_benchmark.cc | 2 +- absl/container/inlined_vector_test.cc | 2 +- absl/container/internal/common.h | 2 +- absl/container/internal/compressed_tuple.h | 6 +++--- 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 | 2 +- absl/container/internal/hash_function_defaults.h | 2 +- absl/container/internal/hash_function_defaults_test.cc | 2 +- absl/container/internal/hash_generator_testing.cc | 2 +- absl/container/internal/hash_generator_testing.h | 2 +- absl/container/internal/hash_policy_testing.h | 2 +- absl/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 | 2 +- absl/container/internal/hashtablez_sampler.cc | 2 +- absl/container/internal/hashtablez_sampler.h | 2 +- .../internal/hashtablez_sampler_force_weak_definition.cc | 2 +- absl/container/internal/hashtablez_sampler_test.cc | 2 +- absl/container/internal/have_sse.h | 2 +- absl/container/internal/layout.h | 2 +- absl/container/internal/layout_test.cc | 2 +- absl/container/internal/node_hash_policy.h | 2 +- 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 | 4 ++-- absl/container/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/test_instance_tracker_test.cc | 2 +- absl/container/internal/tracked.h | 2 +- absl/container/internal/unordered_map_constructor_test.h | 2 +- absl/container/internal/unordered_map_lookup_test.h | 2 +- absl/container/internal/unordered_map_modifiers_test.h | 2 +- absl/container/internal/unordered_map_test.cc | 2 +- absl/container/internal/unordered_set_constructor_test.h | 2 +- absl/container/internal/unordered_set_lookup_test.h | 2 +- absl/container/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 | 2 +- absl/debugging/CMakeLists.txt | 2 +- absl/debugging/failure_signal_handler.cc | 2 +- absl/debugging/failure_signal_handler.h | 2 +- absl/debugging/failure_signal_handler_test.cc | 2 +- absl/debugging/internal/address_is_readable.cc | 2 +- absl/debugging/internal/address_is_readable.h | 2 +- absl/debugging/internal/demangle.cc | 6 +++--- absl/debugging/internal/demangle.h | 2 +- absl/debugging/internal/demangle_test.cc | 2 +- absl/debugging/internal/elf_mem_image.cc | 2 +- absl/debugging/internal/elf_mem_image.h | 2 +- absl/debugging/internal/examine_stack.cc | 2 +- absl/debugging/internal/examine_stack.h | 2 +- absl/debugging/internal/stack_consumption.cc | 2 +- absl/debugging/internal/stack_consumption.h | 2 +- absl/debugging/internal/stack_consumption_test.cc | 2 +- absl/debugging/internal/stacktrace_config.h | 2 +- absl/debugging/internal/stacktrace_powerpc-inl.inc | 6 +++--- absl/debugging/internal/stacktrace_win32-inl.inc | 4 ++-- absl/debugging/internal/stacktrace_x86-inl.inc | 2 +- absl/debugging/internal/symbolize.h | 2 +- absl/debugging/internal/vdso_support.cc | 2 +- absl/debugging/internal/vdso_support.h | 2 +- absl/debugging/leak_check.cc | 2 +- absl/debugging/leak_check.h | 2 +- absl/debugging/leak_check_disable.cc | 2 +- absl/debugging/leak_check_fail_test.cc | 2 +- absl/debugging/leak_check_test.cc | 2 +- absl/debugging/stacktrace.cc | 2 +- absl/debugging/stacktrace.h | 2 +- absl/debugging/symbolize.cc | 2 +- absl/debugging/symbolize.h | 2 +- absl/debugging/symbolize_elf.inc | 2 +- absl/debugging/symbolize_test.cc | 2 +- absl/debugging/symbolize_unimplemented.inc | 2 +- absl/debugging/symbolize_win32.inc | 2 +- absl/hash/BUILD.bazel | 2 +- absl/hash/CMakeLists.txt | 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 | 4 ++-- absl/hash/internal/city_test.cc | 2 +- absl/hash/internal/hash.cc | 2 +- absl/hash/internal/hash.h | 2 +- absl/hash/internal/print_hash_of.cc | 2 +- absl/hash/internal/spy_hash_state.h | 2 +- absl/memory/BUILD.bazel | 2 +- absl/memory/CMakeLists.txt | 2 +- absl/memory/memory.h | 4 ++-- absl/memory/memory_exception_safety_test.cc | 2 +- absl/memory/memory_test.cc | 2 +- absl/meta/CMakeLists.txt | 2 +- absl/meta/type_traits.h | 6 +++--- absl/meta/type_traits_test.cc | 2 +- absl/numeric/BUILD.bazel | 2 +- absl/numeric/CMakeLists.txt | 2 +- absl/numeric/int128.cc | 4 ++-- absl/numeric/int128.h | 2 +- absl/numeric/int128_benchmark.cc | 2 +- absl/numeric/int128_have_intrinsic.inc | 2 +- absl/numeric/int128_no_intrinsic.inc | 2 +- absl/numeric/int128_stream_test.cc | 2 +- absl/numeric/int128_test.cc | 2 +- absl/strings/BUILD.bazel | 2 +- absl/strings/CMakeLists.txt | 2 +- absl/strings/ascii.cc | 2 +- absl/strings/ascii.h | 2 +- absl/strings/ascii_benchmark.cc | 2 +- absl/strings/ascii_test.cc | 2 +- absl/strings/charconv.cc | 2 +- absl/strings/charconv.h | 2 +- absl/strings/charconv_benchmark.cc | 2 +- absl/strings/charconv_test.cc | 2 +- absl/strings/escaping.cc | 10 +++++----- absl/strings/escaping.h | 6 +++--- absl/strings/escaping_benchmark.cc | 2 +- absl/strings/escaping_test.cc | 2 +- absl/strings/internal/char_map.h | 2 +- absl/strings/internal/char_map_benchmark.cc | 2 +- absl/strings/internal/char_map_test.cc | 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 | 2 +- absl/strings/internal/charconv_parse_test.cc | 2 +- absl/strings/internal/escaping_test_common.h | 2 +- absl/strings/internal/memutil.cc | 2 +- absl/strings/internal/memutil.h | 2 +- absl/strings/internal/memutil_benchmark.cc | 2 +- absl/strings/internal/memutil_test.cc | 2 +- absl/strings/internal/numbers_test_common.h | 2 +- absl/strings/internal/ostringstream.cc | 2 +- absl/strings/internal/ostringstream.h | 2 +- absl/strings/internal/ostringstream_benchmark.cc | 2 +- absl/strings/internal/ostringstream_test.cc | 2 +- absl/strings/internal/pow10_helper.cc | 2 +- absl/strings/internal/pow10_helper.h | 2 +- absl/strings/internal/pow10_helper_test.cc | 2 +- absl/strings/internal/resize_uninitialized.h | 2 +- absl/strings/internal/resize_uninitialized_test.cc | 2 +- absl/strings/internal/stl_type_traits.h | 2 +- absl/strings/internal/str_format/arg_test.cc | 2 +- absl/strings/internal/str_format/extension.cc | 2 +- absl/strings/internal/str_format/extension.h | 2 +- absl/strings/internal/str_format/extension_test.cc | 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_join_internal.h | 2 +- absl/strings/internal/str_split_internal.h | 2 +- absl/strings/internal/utf8.cc | 2 +- absl/strings/internal/utf8.h | 2 +- absl/strings/internal/utf8_test.cc | 2 +- absl/strings/match.cc | 2 +- absl/strings/match.h | 2 +- absl/strings/match_test.cc | 2 +- absl/strings/numbers.cc | 2 +- absl/strings/numbers.h | 6 +++--- absl/strings/numbers_benchmark.cc | 2 +- absl/strings/numbers_test.cc | 2 +- absl/strings/str_cat.cc | 2 +- absl/strings/str_cat.h | 2 +- absl/strings/str_cat_benchmark.cc | 2 +- absl/strings/str_cat_test.cc | 2 +- absl/strings/str_format.h | 2 +- absl/strings/str_join.h | 2 +- absl/strings/str_join_benchmark.cc | 2 +- absl/strings/str_join_test.cc | 2 +- absl/strings/str_replace.cc | 2 +- absl/strings/str_replace.h | 2 +- absl/strings/str_replace_benchmark.cc | 2 +- absl/strings/str_replace_test.cc | 2 +- absl/strings/str_split.cc | 2 +- absl/strings/str_split.h | 2 +- absl/strings/str_split_benchmark.cc | 2 +- absl/strings/str_split_test.cc | 2 +- absl/strings/string_view.cc | 4 ++-- absl/strings/string_view.h | 2 +- absl/strings/string_view_benchmark.cc | 2 +- absl/strings/string_view_test.cc | 2 +- absl/strings/strip.h | 2 +- absl/strings/strip_test.cc | 2 +- absl/strings/substitute.cc | 2 +- absl/strings/substitute.h | 2 +- absl/strings/substitute_test.cc | 2 +- absl/synchronization/BUILD.bazel | 2 +- absl/synchronization/CMakeLists.txt | 2 +- absl/synchronization/barrier.cc | 2 +- absl/synchronization/barrier.h | 2 +- absl/synchronization/barrier_test.cc | 2 +- absl/synchronization/blocking_counter.cc | 2 +- absl/synchronization/blocking_counter.h | 2 +- absl/synchronization/blocking_counter_test.cc | 2 +- absl/synchronization/internal/create_thread_identity.cc | 2 +- absl/synchronization/internal/create_thread_identity.h | 2 +- absl/synchronization/internal/graphcycles.cc | 2 +- absl/synchronization/internal/graphcycles.h | 2 +- absl/synchronization/internal/graphcycles_benchmark.cc | 2 +- absl/synchronization/internal/graphcycles_test.cc | 2 +- absl/synchronization/internal/kernel_timeout.h | 2 +- absl/synchronization/internal/mutex_nonprod.cc | 2 +- absl/synchronization/internal/per_thread_sem.cc | 2 +- absl/synchronization/internal/per_thread_sem.h | 2 +- absl/synchronization/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/lifetime_test.cc | 2 +- absl/synchronization/mutex.cc | 2 +- absl/synchronization/mutex.h | 2 +- absl/synchronization/mutex_benchmark.cc | 2 +- absl/synchronization/mutex_test.cc | 2 +- absl/synchronization/notification.cc | 2 +- absl/synchronization/notification.h | 2 +- absl/synchronization/notification_test.cc | 2 +- absl/time/BUILD.bazel | 2 +- absl/time/CMakeLists.txt | 2 +- absl/time/civil_time.cc | 2 +- absl/time/civil_time.h | 2 +- absl/time/civil_time_benchmark.cc | 2 +- absl/time/civil_time_test.cc | 2 +- absl/time/clock.cc | 2 +- absl/time/clock.h | 2 +- absl/time/clock_benchmark.cc | 2 +- absl/time/clock_test.cc | 2 +- absl/time/duration.cc | 8 ++++---- absl/time/duration_benchmark.cc | 2 +- absl/time/duration_test.cc | 2 +- absl/time/format.cc | 2 +- absl/time/format_benchmark.cc | 2 +- absl/time/format_test.cc | 2 +- absl/time/internal/get_current_time_chrono.inc | 2 +- absl/time/internal/test_util.cc | 2 +- absl/time/internal/test_util.h | 2 +- absl/time/time.cc | 2 +- absl/time/time.h | 2 +- absl/time/time_benchmark.cc | 2 +- absl/time/time_test.cc | 2 +- absl/time/time_zone_test.cc | 2 +- absl/types/BUILD.bazel | 2 +- absl/types/CMakeLists.txt | 2 +- absl/types/any.h | 2 +- absl/types/any_exception_safety_test.cc | 2 +- absl/types/any_test.cc | 2 +- absl/types/bad_any_cast.cc | 2 +- absl/types/bad_any_cast.h | 2 +- absl/types/bad_optional_access.cc | 2 +- absl/types/bad_optional_access.h | 2 +- absl/types/bad_variant_access.cc | 2 +- absl/types/bad_variant_access.h | 2 +- absl/types/internal/variant.h | 2 +- absl/types/optional.cc | 2 +- absl/types/optional.h | 2 +- absl/types/optional_exception_safety_test.cc | 2 +- absl/types/optional_test.cc | 2 +- absl/types/span.h | 2 +- absl/types/span_test.cc | 2 +- absl/types/variant.h | 2 +- absl/types/variant_benchmark.cc | 2 +- absl/types/variant_exception_safety_test.cc | 2 +- absl/types/variant_test.cc | 2 +- absl/utility/CMakeLists.txt | 2 +- absl/utility/utility.h | 6 +++--- absl/utility/utility_test.cc | 2 +- 376 files changed, 410 insertions(+), 410 deletions(-) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index 49ef7dcc..7c81beaf 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/CMake/README.md b/CMake/README.md index 66c37692..02359d36 100644 --- a/CMake/README.md +++ b/CMake/README.md @@ -3,7 +3,7 @@ Abseil comes with a CMake build script ([CMakeLists.txt](../CMakeLists.txt)) that can be used on a wide range of platforms ("C" stands for cross-platform.). If you don't have CMake installed already, you can download it for free from -. +. CMake works by generating native makefiles or build projects that can be used in the compiler environment of your choice. diff --git a/CMakeLists.txt b/CMakeLists.txt index 380ed74f..a56d238b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/LICENSE b/LICENSE index 6b0b1270..ccd61dcf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -193,7 +193,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/README.md b/README.md index e9362be2..2c513ea6 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ the Abseil code, running tests, and getting a simple binary working. ## Building Abseil -[Bazel](http://bazel.build) is the official build system for Abseil, +[Bazel](https://bazel.build) is the official build system for Abseil, which is supported on most major platforms (Linux, Windows, MacOS, for example) and compilers. See the [quickstart](https://abseil.io/docs/cpp/quickstart) for more information on building Abseil using the Bazel build system. @@ -106,9 +106,9 @@ license. See [LICENSE](LICENSE) for more information. For more information about Abseil: -* Consult our [Abseil Introduction](http://abseil.io/about/intro) -* Read [Why Adopt Abseil](http://abseil.io/about/philosophy) to understand our +* Consult our [Abseil Introduction](https://abseil.io/about/intro) +* Read [Why Adopt Abseil](https://abseil.io/about/philosophy) to understand our design philosophy. * Peruse our - [Abseil Compatibility Guarantees](http://abseil.io/about/compatibility) to + [Abseil Compatibility Guarantees](https://abseil.io/about/compatibility) to understand both what we promise to you, and what we expect of you in return. diff --git a/absl/BUILD.bazel b/absl/BUILD.bazel index edd0274c..8e3c1773 100644 --- a/absl/BUILD.bazel +++ b/absl/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/CMakeLists.txt b/absl/CMakeLists.txt index 1d09b193..bba0f3e7 100644 --- a/absl/CMakeLists.txt +++ b/absl/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel index 4314ee86..8d266db5 100644 --- a/absl/algorithm/BUILD.bazel +++ b/absl/algorithm/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt index 87a165c0..c51eb10e 100644 --- a/absl/algorithm/CMakeLists.txt +++ b/absl/algorithm/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/algorithm/algorithm.h b/absl/algorithm/algorithm.h index 3d658643..bb90215d 100644 --- a/absl/algorithm/algorithm.h +++ b/absl/algorithm/algorithm.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -94,7 +94,7 @@ It RotateImpl(It first, It middle, It last, std::false_type) { // then the predicate is never invoked and the function returns false. // // This is a C++11-compatible implementation of C++14 `std::equal`. See -// http://en.cppreference.com/w/cpp/algorithm/equal for more information. +// https://en.cppreference.com/w/cpp/algorithm/equal for more information. template bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred&& pred) { diff --git a/absl/algorithm/algorithm_test.cc b/absl/algorithm/algorithm_test.cc index e4322bc4..81fccb61 100644 --- a/absl/algorithm/algorithm_test.cc +++ b/absl/algorithm/algorithm_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 6d5f6630..7348d632 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc index 1502b17f..04282b89 100644 --- a/absl/algorithm/container_test.cc +++ b/absl/algorithm/container_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/algorithm/equal_benchmark.cc b/absl/algorithm/equal_benchmark.cc index 19c0780c..7bf62c9a 100644 --- a/absl/algorithm/equal_benchmark.cc +++ b/absl/algorithm/equal_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 49ae1824..12a8a130 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 1016a665..936c0d2d 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/attributes.h b/absl/base/attributes.h index fa44012e..dc3a95a4 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/bit_cast_test.cc b/absl/base/bit_cast_test.cc index 8cd878d7..4846add4 100644 --- a/absl/base/bit_cast_test.cc +++ b/absl/base/bit_cast_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/call_once.h b/absl/base/call_once.h index f6c8ebb2..8c4f297c 100644 --- a/absl/base/call_once.h +++ b/absl/base/call_once.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/call_once_test.cc b/absl/base/call_once_test.cc index 183b92ef..9c2a0c44 100644 --- a/absl/base/call_once_test.cc +++ b/absl/base/call_once_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/casts.h b/absl/base/casts.h index 1eef6a61..00196d20 100644 --- a/absl/base/casts.h +++ b/absl/base/casts.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/config.h b/absl/base/config.h index e2ef5e4c..3b81e269 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/config_test.cc b/absl/base/config_test.cc index c839712a..7e0c033d 100644 --- a/absl/base/config_test.cc +++ b/absl/base/config_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/const_init.h b/absl/base/const_init.h index fc88b267..1b2b8c2b 100644 --- a/absl/base/const_init.h +++ b/absl/base/const_init.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/dynamic_annotations.cc b/absl/base/dynamic_annotations.cc index 08c27e51..21e822e5 100644 --- a/absl/base/dynamic_annotations.cc +++ b/absl/base/dynamic_annotations.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h index 7e328d96..cdeb18c2 100644 --- a/absl/base/dynamic_annotations.h +++ b/absl/base/dynamic_annotations.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/exception_safety_testing_test.cc b/absl/base/exception_safety_testing_test.cc index 7518264d..2ed38606 100644 --- a/absl/base/exception_safety_testing_test.cc +++ b/absl/base/exception_safety_testing_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/inline_variable_test.cc b/absl/base/inline_variable_test.cc index 5499189a..471f7063 100644 --- a/absl/base/inline_variable_test.cc +++ b/absl/base/inline_variable_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/inline_variable_test_a.cc b/absl/base/inline_variable_test_a.cc index a3bf3b68..d0b8e7d3 100644 --- a/absl/base/inline_variable_test_a.cc +++ b/absl/base/inline_variable_test_a.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/inline_variable_test_b.cc b/absl/base/inline_variable_test_b.cc index b4b9393a..931d56d0 100644 --- a/absl/base/inline_variable_test_b.cc +++ b/absl/base/inline_variable_test_b.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/atomic_hook.h b/absl/base/internal/atomic_hook.h index b458511b..803e9059 100644 --- a/absl/base/internal/atomic_hook.h +++ b/absl/base/internal/atomic_hook.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/atomic_hook_test.cc b/absl/base/internal/atomic_hook_test.cc index cf740757..ecc80406 100644 --- a/absl/base/internal/atomic_hook_test.cc +++ b/absl/base/internal/atomic_hook_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/bits.h b/absl/base/internal/bits.h index bc7faaee..b0780f2d 100644 --- a/absl/base/internal/bits.h +++ b/absl/base/internal/bits.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/bits_test.cc b/absl/base/internal/bits_test.cc index e5d991d6..7855fa62 100644 --- a/absl/base/internal/bits_test.cc +++ b/absl/base/internal/bits_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/cycleclock.cc b/absl/base/internal/cycleclock.cc index 9eb13b8c..4b553c29 100644 --- a/absl/base/internal/cycleclock.cc +++ b/absl/base/internal/cycleclock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/cycleclock.h b/absl/base/internal/cycleclock.h index 9853a66c..7874db71 100644 --- a/absl/base/internal/cycleclock.h +++ b/absl/base/internal/cycleclock.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/direct_mmap.h b/absl/base/internal/direct_mmap.h index 654a6007..0401ddfa 100644 --- a/absl/base/internal/direct_mmap.h +++ b/absl/base/internal/direct_mmap.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/endian.h b/absl/base/internal/endian.h index 3f59184a..6b828b6e 100644 --- a/absl/base/internal/endian.h +++ b/absl/base/internal/endian.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/endian_test.cc b/absl/base/internal/endian_test.cc index e2769155..98a099e4 100644 --- a/absl/base/internal/endian_test.cc +++ b/absl/base/internal/endian_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/exception_safety_testing.cc b/absl/base/internal/exception_safety_testing.cc index 8207b7d7..6ef4325c 100644 --- a/absl/base/internal/exception_safety_testing.cc +++ b/absl/base/internal/exception_safety_testing.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/exception_safety_testing.h b/absl/base/internal/exception_safety_testing.h index 07ce47d4..be38ba54 100644 --- a/absl/base/internal/exception_safety_testing.h +++ b/absl/base/internal/exception_safety_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -558,8 +558,8 @@ class ThrowingValue : private exceptions_internal::TrackedObject { // We provide both regular and templated operator delete because if only the // templated version is provided as we did with operator new, the compiler has // no way of knowing which overload of operator delete to call. See - // http://en.cppreference.com/w/cpp/memory/new/operator_delete and - // http://en.cppreference.com/w/cpp/language/delete for the gory details. + // https://en.cppreference.com/w/cpp/memory/new/operator_delete and + // https://en.cppreference.com/w/cpp/language/delete for the gory details. void operator delete(void* p) noexcept { ::operator delete(p); } template diff --git a/absl/base/internal/exception_testing.h b/absl/base/internal/exception_testing.h index 0cf7918e..01b54655 100644 --- a/absl/base/internal/exception_testing.h +++ b/absl/base/internal/exception_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/hide_ptr.h b/absl/base/internal/hide_ptr.h index 45cf4389..cf8f4080 100644 --- a/absl/base/internal/hide_ptr.h +++ b/absl/base/internal/hide_ptr.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/identity.h b/absl/base/internal/identity.h index a1a5d70a..086447c6 100644 --- a/absl/base/internal/identity.h +++ b/absl/base/internal/identity.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/inline_variable.h b/absl/base/internal/inline_variable.h index f7bb8c56..130d8c24 100644 --- a/absl/base/internal/inline_variable.h +++ b/absl/base/internal/inline_variable.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/inline_variable_testing.h b/absl/base/internal/inline_variable_testing.h index a0dd2bb2..15dc481e 100644 --- a/absl/base/internal/inline_variable_testing.h +++ b/absl/base/internal/inline_variable_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/invoke.h b/absl/base/internal/invoke.h index 8c3f4f60..8da2869a 100644 --- a/absl/base/internal/invoke.h +++ b/absl/base/internal/invoke.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/low_level_alloc.cc b/absl/base/internal/low_level_alloc.cc index 4af9c05d..5a8199e6 100644 --- a/absl/base/internal/low_level_alloc.cc +++ b/absl/base/internal/low_level_alloc.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/low_level_alloc.h b/absl/base/internal/low_level_alloc.h index fba9466a..f83c7bc8 100644 --- a/absl/base/internal/low_level_alloc.h +++ b/absl/base/internal/low_level_alloc.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/low_level_alloc_test.cc b/absl/base/internal/low_level_alloc_test.cc index cf2b3632..d2d31820 100644 --- a/absl/base/internal/low_level_alloc_test.cc +++ b/absl/base/internal/low_level_alloc_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/low_level_scheduling.h b/absl/base/internal/low_level_scheduling.h index e716f2b4..2a5a3847 100644 --- a/absl/base/internal/low_level_scheduling.h +++ b/absl/base/internal/low_level_scheduling.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/per_thread_tls.h b/absl/base/internal/per_thread_tls.h index 56359853..cf5e97a0 100644 --- a/absl/base/internal/per_thread_tls.h +++ b/absl/base/internal/per_thread_tls.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/pretty_function.h b/absl/base/internal/pretty_function.h index 01b0547b..35d51676 100644 --- a/absl/base/internal/pretty_function.h +++ b/absl/base/internal/pretty_function.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/raw_logging.cc b/absl/base/internal/raw_logging.cc index d9485a66..b5a05e8c 100644 --- a/absl/base/internal/raw_logging.cc +++ b/absl/base/internal/raw_logging.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index f34e263e..4cbbbe59 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/scheduling_mode.h b/absl/base/internal/scheduling_mode.h index 1b6497ad..d5b4b7fd 100644 --- a/absl/base/internal/scheduling_mode.h +++ b/absl/base/internal/scheduling_mode.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock.cc b/absl/base/internal/spinlock.cc index 28ba1af7..7354438f 100644 --- a/absl/base/internal/spinlock.cc +++ b/absl/base/internal/spinlock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock.h b/absl/base/internal/spinlock.h index eb3eec9c..4a316399 100644 --- a/absl/base/internal/spinlock.h +++ b/absl/base/internal/spinlock.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock_akaros.inc b/absl/base/internal/spinlock_akaros.inc index 051c8cf8..bc468940 100644 --- a/absl/base/internal/spinlock_akaros.inc +++ b/absl/base/internal/spinlock_akaros.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock_benchmark.cc b/absl/base/internal/spinlock_benchmark.cc index 907d3e27..0451c65f 100644 --- a/absl/base/internal/spinlock_benchmark.cc +++ b/absl/base/internal/spinlock_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc index 3bbd4954..28e29d19 100644 --- a/absl/base/internal/spinlock_linux.inc +++ b/absl/base/internal/spinlock_linux.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock_posix.inc b/absl/base/internal/spinlock_posix.inc index 0098c1c7..f025b5f8 100644 --- a/absl/base/internal/spinlock_posix.inc +++ b/absl/base/internal/spinlock_posix.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock_wait.cc b/absl/base/internal/spinlock_wait.cc index 7e4f4352..fac8a21d 100644 --- a/absl/base/internal/spinlock_wait.cc +++ b/absl/base/internal/spinlock_wait.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock_wait.h b/absl/base/internal/spinlock_wait.h index 5c6cc7fd..6642ce1a 100644 --- a/absl/base/internal/spinlock_wait.h +++ b/absl/base/internal/spinlock_wait.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/spinlock_win32.inc b/absl/base/internal/spinlock_win32.inc index 32c8fc0b..78654b5b 100644 --- a/absl/base/internal/spinlock_win32.inc +++ b/absl/base/internal/spinlock_win32.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index db41bacc..4dd3adda 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/sysinfo.h b/absl/base/internal/sysinfo.h index 5bd1c500..b864a597 100644 --- a/absl/base/internal/sysinfo.h +++ b/absl/base/internal/sysinfo.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/sysinfo_test.cc b/absl/base/internal/sysinfo_test.cc index e0d9aab9..247f3d88 100644 --- a/absl/base/internal/sysinfo_test.cc +++ b/absl/base/internal/sysinfo_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/thread_identity.cc b/absl/base/internal/thread_identity.cc index cff9c1b4..91273a6b 100644 --- a/absl/base/internal/thread_identity.cc +++ b/absl/base/internal/thread_identity.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/thread_identity.h b/absl/base/internal/thread_identity.h index 3b3b7b75..dde3e010 100644 --- a/absl/base/internal/thread_identity.h +++ b/absl/base/internal/thread_identity.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/thread_identity_benchmark.cc b/absl/base/internal/thread_identity_benchmark.cc index 242522b4..0ae10f2b 100644 --- a/absl/base/internal/thread_identity_benchmark.cc +++ b/absl/base/internal/thread_identity_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/thread_identity_test.cc b/absl/base/internal/thread_identity_test.cc index ecb8af68..13bfbe3b 100644 --- a/absl/base/internal/thread_identity_test.cc +++ b/absl/base/internal/thread_identity_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/throw_delegate.cc b/absl/base/internal/throw_delegate.cc index 1c40efcb..8e928b8a 100644 --- a/absl/base/internal/throw_delegate.cc +++ b/absl/base/internal/throw_delegate.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/throw_delegate.h b/absl/base/internal/throw_delegate.h index 70e2d770..03c700b5 100644 --- a/absl/base/internal/throw_delegate.h +++ b/absl/base/internal/throw_delegate.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/tsan_mutex_interface.h b/absl/base/internal/tsan_mutex_interface.h index 6bb4faed..2a510603 100644 --- a/absl/base/internal/tsan_mutex_interface.h +++ b/absl/base/internal/tsan_mutex_interface.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/unaligned_access.h b/absl/base/internal/unaligned_access.h index f9df3b78..2d667377 100644 --- a/absl/base/internal/unaligned_access.h +++ b/absl/base/internal/unaligned_access.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/unscaledcycleclock.cc b/absl/base/internal/unscaledcycleclock.cc index a12d68bd..593762bc 100644 --- a/absl/base/internal/unscaledcycleclock.cc +++ b/absl/base/internal/unscaledcycleclock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/internal/unscaledcycleclock.h b/absl/base/internal/unscaledcycleclock.h index 049f1cac..d5e186a9 100644 --- a/absl/base/internal/unscaledcycleclock.h +++ b/absl/base/internal/unscaledcycleclock.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/invoke_test.cc b/absl/base/invoke_test.cc index 466bf114..691f5537 100644 --- a/absl/base/invoke_test.cc +++ b/absl/base/invoke_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/log_severity.h b/absl/base/log_severity.h index 5770d362..4b9833eb 100644 --- a/absl/base/log_severity.h +++ b/absl/base/log_severity.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/macros.h b/absl/base/macros.h index 5ed12cb0..5b43d7c2 100644 --- a/absl/base/macros.h +++ b/absl/base/macros.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/optimization.h b/absl/base/optimization.h index 9789c2cc..6974f1f6 100644 --- a/absl/base/optimization.h +++ b/absl/base/optimization.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/policy_checks.h b/absl/base/policy_checks.h index 0a07fc03..699fb1a2 100644 --- a/absl/base/policy_checks.h +++ b/absl/base/policy_checks.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/port.h b/absl/base/port.h index 1c67257f..6c28068d 100644 --- a/absl/base/port.h +++ b/absl/base/port.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/raw_logging_test.cc b/absl/base/raw_logging_test.cc index b21cf651..3d30bd38 100644 --- a/absl/base/raw_logging_test.cc +++ b/absl/base/raw_logging_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index 19170813..b32cea29 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/thread_annotations.h b/absl/base/thread_annotations.h index 2241ace4..a8162d41 100644 --- a/absl/base/thread_annotations.h +++ b/absl/base/thread_annotations.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/base/throw_delegate_test.cc b/absl/base/throw_delegate_test.cc index 0f15df04..a74dd3cd 100644 --- a/absl/base/throw_delegate_test.cc +++ b/absl/base/throw_delegate_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/compiler_config_setting.bzl b/absl/compiler_config_setting.bzl index b77c4f56..f1a87018 100644 --- a/absl/compiler_config_setting.bzl +++ b/absl/compiler_config_setting.bzl @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 04b4f9af..b6592ca5 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 56ea4294..76542be1 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index 6da84411..0161d0a9 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/fixed_array_benchmark.cc b/absl/container/fixed_array_benchmark.cc index b4f0cf2a..ff56f466 100644 --- a/absl/container/fixed_array_benchmark.cc +++ b/absl/container/fixed_array_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/fixed_array_exception_safety_test.cc b/absl/container/fixed_array_exception_safety_test.cc index da63dbfe..826eca61 100644 --- a/absl/container/fixed_array_exception_safety_test.cc +++ b/absl/container/fixed_array_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc index 23cf7bb6..a4f2498b 100644 --- a/absl/container/fixed_array_test.cc +++ b/absl/container/fixed_array_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index f6d28472..dfc497b5 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 7340a747..562305e4 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/flat_hash_set.h b/absl/container/flat_hash_set.h index 84984cc4..f27f174c 100644 --- a/absl/container/flat_hash_set.h +++ b/absl/container/flat_hash_set.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc index ae159a24..b55be59b 100644 --- a/absl/container/flat_hash_set_test.cc +++ b/absl/container/flat_hash_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index e8daf6af..80929e36 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/inlined_vector_benchmark.cc b/absl/container/inlined_vector_benchmark.cc index ddd7b33c..fc928afe 100644 --- a/absl/container/inlined_vector_benchmark.cc +++ b/absl/container/inlined_vector_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 5b1527e9..6037001a 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h index aca1a95d..b06e7113 100644 --- a/absl/container/internal/common.h +++ b/absl/container/internal/common.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/compressed_tuple.h b/absl/container/internal/compressed_tuple.h index b883ae26..b9bd91af 100644 --- a/absl/container/internal/compressed_tuple.h +++ b/absl/container/internal/compressed_tuple.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -27,7 +27,7 @@ // const T2& t2 = value.get<2>(); // ... // -// http://en.cppreference.com/w/cpp/language/ebo +// https://en.cppreference.com/w/cpp/language/ebo #ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ #define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ @@ -141,7 +141,7 @@ struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC // const T2& t2 = value.get<2>(); // ... // -// http://en.cppreference.com/w/cpp/language/ebo +// https://en.cppreference.com/w/cpp/language/ebo template class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple : private internal_compressed_tuple::CompressedTupleImpl< diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc index 04ead100..28e7741c 100644 --- a/absl/container/internal/compressed_tuple_test.cc +++ b/absl/container/internal/compressed_tuple_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index 3a3f9703..e5bb9773 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/container_memory_test.cc b/absl/container/internal/container_memory_test.cc index f1c40582..d6b0495f 100644 --- a/absl/container/internal/container_memory_test.cc +++ b/absl/container/internal/container_memory_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/counting_allocator.h b/absl/container/internal/counting_allocator.h index f4e652d9..4e717bef 100644 --- a/absl/container/internal/counting_allocator.h +++ b/absl/container/internal/counting_allocator.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_function_defaults.h b/absl/container/internal/hash_function_defaults.h index 6d112c79..cb8f03c8 100644 --- a/absl/container/internal/hash_function_defaults.h +++ b/absl/container/internal/hash_function_defaults.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_function_defaults_test.cc b/absl/container/internal/hash_function_defaults_test.cc index cc13576d..82708dbe 100644 --- a/absl/container/internal/hash_function_defaults_test.cc +++ b/absl/container/internal/hash_function_defaults_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_generator_testing.cc b/absl/container/internal/hash_generator_testing.cc index e0fefbff..37a23d60 100644 --- a/absl/container/internal/hash_generator_testing.cc +++ b/absl/container/internal/hash_generator_testing.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_generator_testing.h b/absl/container/internal/hash_generator_testing.h index 6521efe8..27fb84f5 100644 --- a/absl/container/internal/hash_generator_testing.h +++ b/absl/container/internal/hash_generator_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_policy_testing.h b/absl/container/internal/hash_policy_testing.h index 7fb819a7..c57407a0 100644 --- a/absl/container/internal/hash_policy_testing.h +++ b/absl/container/internal/hash_policy_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_policy_testing_test.cc b/absl/container/internal/hash_policy_testing_test.cc index c215c423..0c95eb5e 100644 --- a/absl/container/internal/hash_policy_testing_test.cc +++ b/absl/container/internal/hash_policy_testing_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_policy_traits.h b/absl/container/internal/hash_policy_traits.h index ace50a6c..fd007de7 100644 --- a/absl/container/internal/hash_policy_traits.h +++ b/absl/container/internal/hash_policy_traits.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hash_policy_traits_test.cc b/absl/container/internal/hash_policy_traits_test.cc index 423f1548..e643d189 100644 --- a/absl/container/internal/hash_policy_traits_test.cc +++ b/absl/container/internal/hash_policy_traits_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hashtable_debug.h b/absl/container/internal/hashtable_debug.h index 38050c69..71930004 100644 --- a/absl/container/internal/hashtable_debug.h +++ b/absl/container/internal/hashtable_debug.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hashtable_debug_hooks.h b/absl/container/internal/hashtable_debug_hooks.h index 8f219726..371ce81f 100644 --- a/absl/container/internal/hashtable_debug_hooks.h +++ b/absl/container/internal/hashtable_debug_hooks.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index dc669248..6667d3ad 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 547954f7..aff8d15f 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc index 38a3f260..4ca6ffda 100644 --- a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +++ b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index a6e4ac81..d2435ed8 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/have_sse.h b/absl/container/internal/have_sse.h index 29347889..43414418 100644 --- a/absl/container/internal/have_sse.h +++ b/absl/container/internal/have_sse.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h index 98a72be1..bbdde507 100644 --- a/absl/container/internal/layout.h +++ b/absl/container/internal/layout.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc index 301e9f78..33b72bd3 100644 --- a/absl/container/internal/layout_test.cc +++ b/absl/container/internal/layout_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/node_hash_policy.h b/absl/container/internal/node_hash_policy.h index 065e7009..19b4fc09 100644 --- a/absl/container/internal/node_hash_policy.h +++ b/absl/container/internal/node_hash_policy.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/node_hash_policy_test.cc b/absl/container/internal/node_hash_policy_test.cc index 43d287e3..f1d3ec30 100644 --- a/absl/container/internal/node_hash_policy_test.cc +++ b/absl/container/internal/node_hash_policy_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index e0f5c07c..0014cf80 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc index 180d3fe5..ac2d10a7 100644 --- a/absl/container/internal/raw_hash_set.cc +++ b/absl/container/internal/raw_hash_set.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 8814eb87..c4f198bb 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -515,7 +515,7 @@ inline size_t GrowthToLowerboundCapacity(size_t growth) { // if they are equal, false if they are not. If two keys compare equal, then // their hash values as defined by Hash MUST be equal. // -// Allocator: an Allocator [http://devdocs.io/cpp/concept/allocator] with which +// Allocator: an Allocator [https://devdocs.io/cpp/concept/allocator] with which // the storage of the hashtable will be allocated and the elements will be // constructed and destroyed. template diff --git a/absl/container/internal/raw_hash_set_allocator_test.cc b/absl/container/internal/raw_hash_set_allocator_test.cc index 891fa450..a5eff0b3 100644 --- a/absl/container/internal/raw_hash_set_allocator_test.cc +++ b/absl/container/internal/raw_hash_set_allocator_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index f599fd3d..b684571f 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/test_instance_tracker.cc b/absl/container/internal/test_instance_tracker.cc index b18e0bb7..5a66cb4d 100644 --- a/absl/container/internal/test_instance_tracker.cc +++ b/absl/container/internal/test_instance_tracker.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/test_instance_tracker.h b/absl/container/internal/test_instance_tracker.h index ec45f574..032d16d3 100644 --- a/absl/container/internal/test_instance_tracker.h +++ b/absl/container/internal/test_instance_tracker.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/test_instance_tracker_test.cc b/absl/container/internal/test_instance_tracker_test.cc index 0ae57636..091f428d 100644 --- a/absl/container/internal/test_instance_tracker_test.cc +++ b/absl/container/internal/test_instance_tracker_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/tracked.h b/absl/container/internal/tracked.h index 7d14af03..75173ab0 100644 --- a/absl/container/internal/tracked.h +++ b/absl/container/internal/tracked.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_map_constructor_test.h b/absl/container/internal/unordered_map_constructor_test.h index 837d2317..68817e4e 100644 --- a/absl/container/internal/unordered_map_constructor_test.h +++ b/absl/container/internal/unordered_map_constructor_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_map_lookup_test.h b/absl/container/internal/unordered_map_lookup_test.h index 488e340d..ebd3612b 100644 --- a/absl/container/internal/unordered_map_lookup_test.h +++ b/absl/container/internal/unordered_map_lookup_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_map_modifiers_test.h b/absl/container/internal/unordered_map_modifiers_test.h index 2e1cd633..52a1092e 100644 --- a/absl/container/internal/unordered_map_modifiers_test.h +++ b/absl/container/internal/unordered_map_modifiers_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_map_test.cc b/absl/container/internal/unordered_map_test.cc index 32ab48d0..72567eac 100644 --- a/absl/container/internal/unordered_map_test.cc +++ b/absl/container/internal/unordered_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_set_constructor_test.h b/absl/container/internal/unordered_set_constructor_test.h index 533a6217..f4844683 100644 --- a/absl/container/internal/unordered_set_constructor_test.h +++ b/absl/container/internal/unordered_set_constructor_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_set_lookup_test.h b/absl/container/internal/unordered_set_lookup_test.h index 69f43142..05b32b5d 100644 --- a/absl/container/internal/unordered_set_lookup_test.h +++ b/absl/container/internal/unordered_set_lookup_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_set_modifiers_test.h b/absl/container/internal/unordered_set_modifiers_test.h index 853c4e31..79a8d422 100644 --- a/absl/container/internal/unordered_set_modifiers_test.h +++ b/absl/container/internal/unordered_set_modifiers_test.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/internal/unordered_set_test.cc b/absl/container/internal/unordered_set_test.cc index 1a340af8..6478fac1 100644 --- a/absl/container/internal/unordered_set_test.cc +++ b/absl/container/internal/unordered_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h index bd53c590..a841f5ab 100644 --- a/absl/container/node_hash_map.h +++ b/absl/container/node_hash_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc index 87fd4185..0f2714a7 100644 --- a/absl/container/node_hash_map_test.cc +++ b/absl/container/node_hash_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/node_hash_set.h b/absl/container/node_hash_set.h index 843b11aa..0cd1fe57 100644 --- a/absl/container/node_hash_set.h +++ b/absl/container/node_hash_set.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/container/node_hash_set_test.cc b/absl/container/node_hash_set_test.cc index 5eaac2a5..0ea76e7c 100644 --- a/absl/container/node_hash_set_test.cc +++ b/absl/container/node_hash_set_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 84b994da..c9184f92 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 34511521..dccd4a56 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index c2e56f9d..c6a4d962 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/failure_signal_handler.h b/absl/debugging/failure_signal_handler.h index c57954e5..1beb78b9 100644 --- a/absl/debugging/failure_signal_handler.h +++ b/absl/debugging/failure_signal_handler.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/failure_signal_handler_test.cc b/absl/debugging/failure_signal_handler_test.cc index 15e888be..bb2cc48e 100644 --- a/absl/debugging/failure_signal_handler_test.cc +++ b/absl/debugging/failure_signal_handler_test.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/address_is_readable.cc b/absl/debugging/internal/address_is_readable.cc index 7455aa0b..99c4c64b 100644 --- a/absl/debugging/internal/address_is_readable.cc +++ b/absl/debugging/internal/address_is_readable.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/address_is_readable.h b/absl/debugging/internal/address_is_readable.h index 9d480300..64c3f1ea 100644 --- a/absl/debugging/internal/address_is_readable.h +++ b/absl/debugging/internal/address_is_readable.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 3ee3df51..0d959a98 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -749,8 +749,8 @@ static bool ParseSourceName(State *state) { // ::= L [] // // References: -// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 -// http://gcc.gnu.org/viewcvs?view=rev&revision=124467 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 +// https://gcc.gnu.org/viewcvs?view=rev&revision=124467 static bool ParseLocalSourceName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; diff --git a/absl/debugging/internal/demangle.h b/absl/debugging/internal/demangle.h index 2e75564e..81bb0dfd 100644 --- a/absl/debugging/internal/demangle.h +++ b/absl/debugging/internal/demangle.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index b9d9008f..d410a232 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/elf_mem_image.cc b/absl/debugging/internal/elf_mem_image.cc index 3f747e7f..e7408bca 100644 --- a/absl/debugging/internal/elf_mem_image.cc +++ b/absl/debugging/internal/elf_mem_image.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h index 3b577268..99b37580 100644 --- a/absl/debugging/internal/elf_mem_image.h +++ b/absl/debugging/internal/elf_mem_image.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/examine_stack.cc b/absl/debugging/internal/examine_stack.cc index faf88836..1ebc788f 100644 --- a/absl/debugging/internal/examine_stack.cc +++ b/absl/debugging/internal/examine_stack.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/examine_stack.h b/absl/debugging/internal/examine_stack.h index a16c03b2..56c9763e 100644 --- a/absl/debugging/internal/examine_stack.h +++ b/absl/debugging/internal/examine_stack.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/stack_consumption.cc b/absl/debugging/internal/stack_consumption.cc index 2b3b972e..4b05f495 100644 --- a/absl/debugging/internal/stack_consumption.cc +++ b/absl/debugging/internal/stack_consumption.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/stack_consumption.h b/absl/debugging/internal/stack_consumption.h index 4c5fa0f0..b860a3c1 100644 --- a/absl/debugging/internal/stack_consumption.h +++ b/absl/debugging/internal/stack_consumption.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/stack_consumption_test.cc b/absl/debugging/internal/stack_consumption_test.cc index 5ce3846e..68bfa126 100644 --- a/absl/debugging/internal/stack_consumption_test.cc +++ b/absl/debugging/internal/stack_consumption_test.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h index 578e4968..d4e8480a 100644 --- a/absl/debugging/internal/stacktrace_config.h +++ b/absl/debugging/internal/stacktrace_config.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/stacktrace_powerpc-inl.inc b/absl/debugging/internal/stacktrace_powerpc-inl.inc index 860ac2b3..9e0f2aad 100644 --- a/absl/debugging/internal/stacktrace_powerpc-inl.inc +++ b/absl/debugging/internal/stacktrace_powerpc-inl.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -14,8 +14,8 @@ // // Produce stack trace. I'm guessing (hoping!) the code is much like // for x86. For apple machines, at least, it seems to be; see -// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html -// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK +// https://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html +// https://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK // Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882 #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_ diff --git a/absl/debugging/internal/stacktrace_win32-inl.inc b/absl/debugging/internal/stacktrace_win32-inl.inc index a8f8a56a..b46491f8 100644 --- a/absl/debugging/internal/stacktrace_win32-inl.inc +++ b/absl/debugging/internal/stacktrace_win32-inl.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -32,7 +32,7 @@ // server. // // This code is inspired by a patch from David Vitek: -// http://code.google.com/p/google-perftools/issues/detail?id=83 +// https://code.google.com/p/google-perftools/issues/detail?id=83 #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_WIN32_INL_H_ #define 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 ac85b920..248966b0 100644 --- a/absl/debugging/internal/stacktrace_x86-inl.inc +++ b/absl/debugging/internal/stacktrace_x86-inl.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/symbolize.h b/absl/debugging/internal/symbolize.h index d719eda9..3e537893 100644 --- a/absl/debugging/internal/symbolize.h +++ b/absl/debugging/internal/symbolize.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc index 44ec7c02..d13ef25d 100644 --- a/absl/debugging/internal/vdso_support.cc +++ b/absl/debugging/internal/vdso_support.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/internal/vdso_support.h b/absl/debugging/internal/vdso_support.h index 8002c740..9895b48d 100644 --- a/absl/debugging/internal/vdso_support.h +++ b/absl/debugging/internal/vdso_support.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc index e01e5f8c..a1cae969 100644 --- a/absl/debugging/leak_check.cc +++ b/absl/debugging/leak_check.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h index c930684e..4d489c58 100644 --- a/absl/debugging/leak_check.h +++ b/absl/debugging/leak_check.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/leak_check_disable.cc b/absl/debugging/leak_check_disable.cc index df22c1ca..924d6e3d 100644 --- a/absl/debugging/leak_check_disable.cc +++ b/absl/debugging/leak_check_disable.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/leak_check_fail_test.cc b/absl/debugging/leak_check_fail_test.cc index bf541fe8..2887ceab 100644 --- a/absl/debugging/leak_check_fail_test.cc +++ b/absl/debugging/leak_check_fail_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/leak_check_test.cc b/absl/debugging/leak_check_test.cc index febd1ee4..93a7edd2 100644 --- a/absl/debugging/leak_check_test.cc +++ b/absl/debugging/leak_check_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/stacktrace.cc b/absl/debugging/stacktrace.cc index 7bbd65ac..9935adfa 100644 --- a/absl/debugging/stacktrace.cc +++ b/absl/debugging/stacktrace.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/stacktrace.h b/absl/debugging/stacktrace.h index 8b831e26..3fc1c03f 100644 --- a/absl/debugging/stacktrace.h +++ b/absl/debugging/stacktrace.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/symbolize.cc b/absl/debugging/symbolize.cc index a35e24cc..24e3a7f0 100644 --- a/absl/debugging/symbolize.cc +++ b/absl/debugging/symbolize.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/symbolize.h b/absl/debugging/symbolize.h index 24e6e647..a73dbd9e 100644 --- a/absl/debugging/symbolize.h +++ b/absl/debugging/symbolize.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index 5b16bb8b..05fc2979 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index dcb52695..fc3ed93e 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/symbolize_unimplemented.inc b/absl/debugging/symbolize_unimplemented.inc index 98b3a9ae..7c580fe4 100644 --- a/absl/debugging/symbolize_unimplemented.inc +++ b/absl/debugging/symbolize_unimplemented.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/debugging/symbolize_win32.inc b/absl/debugging/symbolize_win32.inc index e3fff74d..17ea618a 100644 --- a/absl/debugging/symbolize_win32.inc +++ b/absl/debugging/symbolize_win32.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index 5f24b999..69860d98 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt index 8f97d7cc..4cafc133 100644 --- a/absl/hash/CMakeLists.txt +++ b/absl/hash/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/hash.h b/absl/hash/hash.h index 3b1d6eab..94cb6747 100644 --- a/absl/hash/hash.h +++ b/absl/hash/hash.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 97c3449a..d9ebd30f 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/hash_testing.h b/absl/hash/hash_testing.h index 06d09499..c45bc154 100644 --- a/absl/hash/hash_testing.h +++ b/absl/hash/hash_testing.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/internal/city.cc b/absl/hash/internal/city.cc index 122906fa..dc7650a7 100644 --- a/absl/hash/internal/city.cc +++ b/absl/hash/internal/city.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/internal/city.h b/absl/hash/internal/city.h index 16df5563..1b3b4ef9 100644 --- a/absl/hash/internal/city.h +++ b/absl/hash/internal/city.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// http://code.google.com/p/cityhash/ +// https://code.google.com/p/cityhash/ // // This file provides a few functions for hashing strings. All of them are // high-quality functions in the sense that they pass standard tests such diff --git a/absl/hash/internal/city_test.cc b/absl/hash/internal/city_test.cc index 0427cd1a..71b4ecce 100644 --- a/absl/hash/internal/city_test.cc +++ b/absl/hash/internal/city_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/internal/hash.cc b/absl/hash/internal/hash.cc index 4bf64096..4ab7a9f8 100644 --- a/absl/hash/internal/hash.cc +++ b/absl/hash/internal/hash.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 4db816c7..2a45bc84 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/internal/print_hash_of.cc b/absl/hash/internal/print_hash_of.cc index b6df31cc..c392125a 100644 --- a/absl/hash/internal/print_hash_of.cc +++ b/absl/hash/internal/print_hash_of.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h index 102e05de..c4cc8d07 100644 --- a/absl/hash/internal/spy_hash_state.h +++ b/absl/hash/internal/spy_hash_state.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/memory/BUILD.bazel b/absl/memory/BUILD.bazel index c0da9ce1..7c6366fe 100644 --- a/absl/memory/BUILD.bazel +++ b/absl/memory/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/memory/CMakeLists.txt b/absl/memory/CMakeLists.txt index 4b494dc0..0a812203 100644 --- a/absl/memory/CMakeLists.txt +++ b/absl/memory/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/memory/memory.h b/absl/memory/memory.h index 75506a74..a0d0714f 100644 --- a/absl/memory/memory.h +++ b/absl/memory/memory.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -120,7 +120,7 @@ using std::make_unique; // // For more background on why `std::unique_ptr(new T(a,b))` is problematic, // see Herb Sutter's explanation on -// (Exception-Safe Function Calls)[http://herbsutter.com/gotw/_102/]. +// (Exception-Safe Function Calls)[https://herbsutter.com/gotw/_102/]. // (In general, reviewers should treat `new T(a,b)` with scrutiny.) // // Example usage: diff --git a/absl/memory/memory_exception_safety_test.cc b/absl/memory/memory_exception_safety_test.cc index 00d2b192..a1c39707 100644 --- a/absl/memory/memory_exception_safety_test.cc +++ b/absl/memory/memory_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/memory/memory_test.cc b/absl/memory/memory_test.cc index 21fe32f9..8905433c 100644 --- a/absl/memory/memory_test.cc +++ b/absl/memory/memory_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/meta/CMakeLists.txt b/absl/meta/CMakeLists.txt index 4358db57..74d4a543 100644 --- a/absl/meta/CMakeLists.txt +++ b/absl/meta/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 88853974..8a788dea 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -22,7 +22,7 @@ // support type inference, classification, and transformation, as well as // make it easier to write templates based on generic type behavior. // -// See http://en.cppreference.com/w/cpp/header/type_traits +// See https://en.cppreference.com/w/cpp/header/type_traits // // WARNING: use of many of the constructs in this header will count as "complex // template metaprogramming", so before proceeding, please carefully consider @@ -246,7 +246,7 @@ struct is_trivially_destructible // For the purposes of this check, the call to std::declval is considered // trivial." // -// Notes from http://en.cppreference.com/w/cpp/types/is_constructible: +// Notes from https://en.cppreference.com/w/cpp/types/is_constructible: // In many implementations, is_nothrow_constructible also checks if the // destructor throws because it is effectively noexcept(T(arg)). Same // applies to is_trivially_constructible, which, in these implementations, also diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index f51f5ded..29a6db69 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/BUILD.bazel b/absl/numeric/BUILD.bazel index c906b8d7..7cd7ee19 100644 --- a/absl/numeric/BUILD.bazel +++ b/absl/numeric/BUILD.bazel @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/CMakeLists.txt b/absl/numeric/CMakeLists.txt index 42468a6a..d26141c7 100644 --- a/absl/numeric/CMakeLists.txt +++ b/absl/numeric/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index 3c37f252..33f528ce 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -65,7 +65,7 @@ static inline int Fls128(uint128 n) { // Long division/modulo for uint128 implemented using the shift-subtract // division algorithm adapted from: -// http://stackoverflow.com/questions/5386377/division-without-using +// https://stackoverflow.com/questions/5386377/division-without-using void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret, uint128* remainder_ret) { assert(divisor != 0); diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 3e7d2d9f..c0ec03d4 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/int128_benchmark.cc b/absl/numeric/int128_benchmark.cc index 1cb7d0ed..a5502d92 100644 --- a/absl/numeric/int128_benchmark.cc +++ b/absl/numeric/int128_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/int128_have_intrinsic.inc b/absl/numeric/int128_have_intrinsic.inc index 0c8164a5..c7ea6834 100644 --- a/absl/numeric/int128_have_intrinsic.inc +++ b/absl/numeric/int128_have_intrinsic.inc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/int128_no_intrinsic.inc b/absl/numeric/int128_no_intrinsic.inc index 08d68ac3..046cb9b3 100644 --- a/absl/numeric/int128_no_intrinsic.inc +++ b/absl/numeric/int128_no_intrinsic.inc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/int128_stream_test.cc b/absl/numeric/int128_stream_test.cc index 09efaad4..3cfa9dc1 100644 --- a/absl/numeric/int128_stream_test.cc +++ b/absl/numeric/int128_stream_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc index 4a6eb455..216ec50c 100644 --- a/absl/numeric/int128_test.cc +++ b/absl/numeric/int128_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 7635a619..8afe8177 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index aed54dc4..d3393a39 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/ascii.cc b/absl/strings/ascii.cc index c9481e88..3f7c581f 100644 --- a/absl/strings/ascii.cc +++ b/absl/strings/ascii.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/ascii.h b/absl/strings/ascii.h index 48a9da22..f9e4fd1d 100644 --- a/absl/strings/ascii.h +++ b/absl/strings/ascii.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/ascii_benchmark.cc b/absl/strings/ascii_benchmark.cc index 8dea4b8c..aca458c8 100644 --- a/absl/strings/ascii_benchmark.cc +++ b/absl/strings/ascii_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/ascii_test.cc b/absl/strings/ascii_test.cc index 9903b049..5ecd23f8 100644 --- a/absl/strings/ascii_test.cc +++ b/absl/strings/ascii_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/charconv.cc b/absl/strings/charconv.cc index d0aa1913..bc07e7ab 100644 --- a/absl/strings/charconv.cc +++ b/absl/strings/charconv.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/charconv.h b/absl/strings/charconv.h index 07353829..59f74bf0 100644 --- a/absl/strings/charconv.h +++ b/absl/strings/charconv.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/charconv_benchmark.cc b/absl/strings/charconv_benchmark.cc index fd83f44e..644b2abd 100644 --- a/absl/strings/charconv_benchmark.cc +++ b/absl/strings/charconv_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/charconv_test.cc b/absl/strings/charconv_test.cc index d6a0a759..b58fad26 100644 --- a/absl/strings/charconv_test.cc +++ b/absl/strings/charconv_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/escaping.cc b/absl/strings/escaping.cc index 0950ab9e..bc8307e1 100644 --- a/absl/strings/escaping.cc +++ b/absl/strings/escaping.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -788,7 +788,7 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { // Base64 encodes three bytes of input at a time. If the input is not // divisible by three, we pad as appropriate. // - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // Special processing is performed if fewer than 24 bits are available // at the end of the data being encoded. A full encoding quantum is // always completed at the end of a quantity. When fewer than 24 input @@ -802,12 +802,12 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { size_t len = (input_len / 3) * 4; if (input_len % 3 == 0) { - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // (1) the final quantum of encoding input is an integral multiple of 24 // bits; here, the final unit of encoded output will be an integral // multiple of 4 characters with no "=" padding, } else if (input_len % 3 == 1) { - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // (2) the final quantum of encoding input is exactly 8 bits; here, the // final unit of encoded output will be two characters followed by two // "=" padding characters, or @@ -816,7 +816,7 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { len += 2; } } else { // (input_len % 3 == 2) - // (from http://tools.ietf.org/html/rfc3548) + // (from https://tools.ietf.org/html/rfc3548) // (3) the final quantum of encoding input is exactly 16 bits; here, the // final unit of encoded output will be three characters followed by one // "=" padding character. diff --git a/absl/strings/escaping.h b/absl/strings/escaping.h index 29659730..03ab0ae7 100644 --- a/absl/strings/escaping.h +++ b/absl/strings/escaping.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -38,7 +38,7 @@ namespace absl { // CUnescape() // // Unescapes a `source` string and copies it into `dest`, rewriting C-style -// escape sequences (http://en.cppreference.com/w/cpp/language/escape) into +// escape sequences (https://en.cppreference.com/w/cpp/language/escape) into // their proper code point equivalents, returning `true` if successful. // // The following unescape sequences can be handled: @@ -80,7 +80,7 @@ inline bool CUnescape(absl::string_view source, std::string* dest) { // CEscape() // // Escapes a 'src' string using C-style escapes sequences -// (http://en.cppreference.com/w/cpp/language/escape), escaping other +// (https://en.cppreference.com/w/cpp/language/escape), escaping other // non-printable/non-whitespace bytes as octal sequences (e.g. "\377"). // // Example: diff --git a/absl/strings/escaping_benchmark.cc b/absl/strings/escaping_benchmark.cc index 0f791f4e..10d5b033 100644 --- a/absl/strings/escaping_benchmark.cc +++ b/absl/strings/escaping_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/escaping_test.cc b/absl/strings/escaping_test.cc index 77846dd2..d433b4c5 100644 --- a/absl/strings/escaping_test.cc +++ b/absl/strings/escaping_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/char_map.h b/absl/strings/internal/char_map.h index 8d92963a..b9108b8c 100644 --- a/absl/strings/internal/char_map.h +++ b/absl/strings/internal/char_map.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/char_map_benchmark.cc b/absl/strings/internal/char_map_benchmark.cc index c45f3157..5cef967b 100644 --- a/absl/strings/internal/char_map_benchmark.cc +++ b/absl/strings/internal/char_map_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/char_map_test.cc b/absl/strings/internal/char_map_test.cc index c3601e10..d3306241 100644 --- a/absl/strings/internal/char_map_test.cc +++ b/absl/strings/internal/char_map_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/charconv_bigint.cc b/absl/strings/internal/charconv_bigint.cc index 3e7296e7..95d471d9 100644 --- a/absl/strings/internal/charconv_bigint.cc +++ b/absl/strings/internal/charconv_bigint.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/charconv_bigint.h b/absl/strings/internal/charconv_bigint.h index 9d1a1bff..7da9a7e7 100644 --- a/absl/strings/internal/charconv_bigint.h +++ b/absl/strings/internal/charconv_bigint.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/charconv_bigint_test.cc b/absl/strings/internal/charconv_bigint_test.cc index 9b635788..745714ac 100644 --- a/absl/strings/internal/charconv_bigint_test.cc +++ b/absl/strings/internal/charconv_bigint_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/charconv_parse.cc b/absl/strings/internal/charconv_parse.cc index 7e4dabc2..f3c72324 100644 --- a/absl/strings/internal/charconv_parse.cc +++ b/absl/strings/internal/charconv_parse.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/charconv_parse.h b/absl/strings/internal/charconv_parse.h index 7a5c0874..44d06b2e 100644 --- a/absl/strings/internal/charconv_parse.h +++ b/absl/strings/internal/charconv_parse.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/charconv_parse_test.cc b/absl/strings/internal/charconv_parse_test.cc index f48b9aee..9511c987 100644 --- a/absl/strings/internal/charconv_parse_test.cc +++ b/absl/strings/internal/charconv_parse_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/escaping_test_common.h b/absl/strings/internal/escaping_test_common.h index cc41f431..bd803031 100644 --- a/absl/strings/internal/escaping_test_common.h +++ b/absl/strings/internal/escaping_test_common.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/memutil.cc b/absl/strings/internal/memutil.cc index a0de70df..77aa63c2 100644 --- a/absl/strings/internal/memutil.cc +++ b/absl/strings/internal/memutil.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/memutil.h b/absl/strings/internal/memutil.h index 7de383b1..7c071a82 100644 --- a/absl/strings/internal/memutil.h +++ b/absl/strings/internal/memutil.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/memutil_benchmark.cc b/absl/strings/internal/memutil_benchmark.cc index 77915adb..dc95c3e5 100644 --- a/absl/strings/internal/memutil_benchmark.cc +++ b/absl/strings/internal/memutil_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/memutil_test.cc b/absl/strings/internal/memutil_test.cc index 09424de9..d8681ddf 100644 --- a/absl/strings/internal/memutil_test.cc +++ b/absl/strings/internal/memutil_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/numbers_test_common.h b/absl/strings/internal/numbers_test_common.h index f6241ff3..28247205 100644 --- a/absl/strings/internal/numbers_test_common.h +++ b/absl/strings/internal/numbers_test_common.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/ostringstream.cc b/absl/strings/internal/ostringstream.cc index 6ee2b109..d0f0f84b 100644 --- a/absl/strings/internal/ostringstream.cc +++ b/absl/strings/internal/ostringstream.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/ostringstream.h b/absl/strings/internal/ostringstream.h index 316379ca..20792015 100644 --- a/absl/strings/internal/ostringstream.h +++ b/absl/strings/internal/ostringstream.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/ostringstream_benchmark.cc b/absl/strings/internal/ostringstream_benchmark.cc index c93f9690..5979f182 100644 --- a/absl/strings/internal/ostringstream_benchmark.cc +++ b/absl/strings/internal/ostringstream_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/ostringstream_test.cc b/absl/strings/internal/ostringstream_test.cc index 069a0e1f..2879e50e 100644 --- a/absl/strings/internal/ostringstream_test.cc +++ b/absl/strings/internal/ostringstream_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/pow10_helper.cc b/absl/strings/internal/pow10_helper.cc index 66be163f..03ed8d07 100644 --- a/absl/strings/internal/pow10_helper.cc +++ b/absl/strings/internal/pow10_helper.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/pow10_helper.h b/absl/strings/internal/pow10_helper.h index fe7e735a..9d1aa710 100644 --- a/absl/strings/internal/pow10_helper.h +++ b/absl/strings/internal/pow10_helper.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/pow10_helper_test.cc b/absl/strings/internal/pow10_helper_test.cc index 9a13d524..a4a68b5d 100644 --- a/absl/strings/internal/pow10_helper_test.cc +++ b/absl/strings/internal/pow10_helper_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/resize_uninitialized.h b/absl/strings/internal/resize_uninitialized.h index 25d602b1..469962b2 100644 --- a/absl/strings/internal/resize_uninitialized.h +++ b/absl/strings/internal/resize_uninitialized.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/resize_uninitialized_test.cc b/absl/strings/internal/resize_uninitialized_test.cc index 43aece8d..c5be0b12 100644 --- a/absl/strings/internal/resize_uninitialized_test.cc +++ b/absl/strings/internal/resize_uninitialized_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/stl_type_traits.h b/absl/strings/internal/stl_type_traits.h index 04c4a532..202ab374 100644 --- a/absl/strings/internal/stl_type_traits.h +++ b/absl/strings/internal/stl_type_traits.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_format/arg_test.cc b/absl/strings/internal/str_format/arg_test.cc index 83d59048..3421fac1 100644 --- a/absl/strings/internal/str_format/arg_test.cc +++ b/absl/strings/internal/str_format/arg_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // #include "absl/strings/internal/str_format/arg.h" diff --git a/absl/strings/internal/str_format/extension.cc b/absl/strings/internal/str_format/extension.cc index c2174703..d7f58159 100644 --- a/absl/strings/internal/str_format/extension.cc +++ b/absl/strings/internal/str_format/extension.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 55be9284..30235e08 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_format/extension_test.cc b/absl/strings/internal/str_format/extension_test.cc index 224fc923..334a1484 100644 --- a/absl/strings/internal/str_format/extension_test.cc +++ b/absl/strings/internal/str_format/extension_test.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_format/output.cc b/absl/strings/internal/str_format/output.cc index d7fef69b..38987b63 100644 --- a/absl/strings/internal/str_format/output.cc +++ b/absl/strings/internal/str_format/output.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_format/output.h b/absl/strings/internal/str_format/output.h index 12ecd99e..42da6417 100644 --- a/absl/strings/internal/str_format/output.h +++ b/absl/strings/internal/str_format/output.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_format/output_test.cc b/absl/strings/internal/str_format/output_test.cc index 305cc6e6..ca93d1e3 100644 --- a/absl/strings/internal/str_format/output_test.cc +++ b/absl/strings/internal/str_format/output_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_join_internal.h b/absl/strings/internal/str_join_internal.h index 6281da6e..7c35f4de 100644 --- a/absl/strings/internal/str_join_internal.h +++ b/absl/strings/internal/str_join_internal.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h index 34390a91..52f62226 100644 --- a/absl/strings/internal/str_split_internal.h +++ b/absl/strings/internal/str_split_internal.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/utf8.cc b/absl/strings/internal/utf8.cc index 2415c2cc..82d36c24 100644 --- a/absl/strings/internal/utf8.cc +++ b/absl/strings/internal/utf8.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/utf8.h b/absl/strings/internal/utf8.h index d2c3c0b0..445d4c35 100644 --- a/absl/strings/internal/utf8.h +++ b/absl/strings/internal/utf8.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/internal/utf8_test.cc b/absl/strings/internal/utf8_test.cc index 6ffa36cd..88dd5036 100644 --- a/absl/strings/internal/utf8_test.cc +++ b/absl/strings/internal/utf8_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/match.cc b/absl/strings/match.cc index a2e9064c..7b24241a 100644 --- a/absl/strings/match.cc +++ b/absl/strings/match.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/match.h b/absl/strings/match.h index 3a4fefd9..5251b7ff 100644 --- a/absl/strings/match.h +++ b/absl/strings/match.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/match_test.cc b/absl/strings/match_test.cc index 0dca33ae..4c313dda 100644 --- a/absl/strings/match_test.cc +++ b/absl/strings/match_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index 60c8fed1..558c3396 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h index dc02bc30..e0f96df9 100644 --- a/absl/strings/numbers.h +++ b/absl/strings/numbers.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -53,7 +53,7 @@ ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view s, 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 http://en.cppreference.com/w/c/string/byte/strtof for details about the +// See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`. 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); @@ -62,7 +62,7 @@ ABSL_MUST_USE_RESULT bool SimpleAtof(absl::string_view str, float* out); // // Converts the given string (optionally followed or preceded by ASCII // whitespace) into a double, which may be rounded on overflow or underflow. -// See http://en.cppreference.com/w/c/string/byte/strtof for details about the +// See https://en.cppreference.com/w/c/string/byte/strtof for details about the // allowed formats for `str`. If any errors are encountered, this function // returns `false`, leaving `out` in an unspecified state. ABSL_MUST_USE_RESULT bool SimpleAtod(absl::string_view str, double* out); diff --git a/absl/strings/numbers_benchmark.cc b/absl/strings/numbers_benchmark.cc index 0570b758..54dbedd3 100644 --- a/absl/strings/numbers_benchmark.cc +++ b/absl/strings/numbers_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index 7edb73eb..b7b03ff0 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_cat.cc b/absl/strings/str_cat.cc index b3a55d13..2667976d 100644 --- a/absl/strings/str_cat.cc +++ b/absl/strings/str_cat.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_cat.h b/absl/strings/str_cat.h index 7b5bedb0..69d6eaad 100644 --- a/absl/strings/str_cat.h +++ b/absl/strings/str_cat.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_cat_benchmark.cc b/absl/strings/str_cat_benchmark.cc index b6df9e30..14c63b3f 100644 --- a/absl/strings/str_cat_benchmark.cc +++ b/absl/strings/str_cat_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_cat_test.cc b/absl/strings/str_cat_test.cc index af459c51..beb15fa9 100644 --- a/absl/strings/str_cat_test.cc +++ b/absl/strings/str_cat_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index 4736bef1..486fe0eb 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_join.h b/absl/strings/str_join.h index 69abc9c1..7345b962 100644 --- a/absl/strings/str_join.h +++ b/absl/strings/str_join.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_join_benchmark.cc b/absl/strings/str_join_benchmark.cc index f423e123..d6f689ff 100644 --- a/absl/strings/str_join_benchmark.cc +++ b/absl/strings/str_join_benchmark.cc @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_join_test.cc b/absl/strings/str_join_test.cc index de9c3551..921d9c2b 100644 --- a/absl/strings/str_join_test.cc +++ b/absl/strings/str_join_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_replace.cc b/absl/strings/str_replace.cc index d01b8b11..280f63d3 100644 --- a/absl/strings/str_replace.cc +++ b/absl/strings/str_replace.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_replace.h b/absl/strings/str_replace.h index 6d284042..30540d02 100644 --- a/absl/strings/str_replace.h +++ b/absl/strings/str_replace.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_replace_benchmark.cc b/absl/strings/str_replace_benchmark.cc index 07fd3a70..95b2dc10 100644 --- a/absl/strings/str_replace_benchmark.cc +++ b/absl/strings/str_replace_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_replace_test.cc b/absl/strings/str_replace_test.cc index 73c69a59..1ca23aff 100644 --- a/absl/strings/str_replace_test.cc +++ b/absl/strings/str_replace_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_split.cc b/absl/strings/str_split.cc index 0a68c52d..25931307 100644 --- a/absl/strings/str_split.cc +++ b/absl/strings/str_split.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_split.h b/absl/strings/str_split.h index dc45bc8a..8eb55089 100644 --- a/absl/strings/str_split.h +++ b/absl/strings/str_split.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_split_benchmark.cc b/absl/strings/str_split_benchmark.cc index 6280568a..28c25e8d 100644 --- a/absl/strings/str_split_benchmark.cc +++ b/absl/strings/str_split_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc index babead92..4b8e7d6b 100644 --- a/absl/strings/str_split_test.cc +++ b/absl/strings/str_split_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc index 4ceeb6bf..cb79d5df 100644 --- a/absl/strings/string_view.cc +++ b/absl/strings/string_view.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -228,7 +228,7 @@ string_view::size_type string_view::find_last_not_of(char c, // member definitions that are required by the C++ standard, resulting in // LNK1169 "multiply defined" errors at link time. __declspec(selectany) asks // MSVC to choose only one definition for the symbol it decorates. See details -// at http://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx +// at https://msdn.microsoft.com/en-us/library/34h23df8(v=vs.100).aspx #ifdef _MSC_VER #define ABSL_STRING_VIEW_SELECTANY __declspec(selectany) #else diff --git a/absl/strings/string_view.h b/absl/strings/string_view.h index 72f0f414..524dbebb 100644 --- a/absl/strings/string_view.h +++ b/absl/strings/string_view.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/string_view_benchmark.cc b/absl/strings/string_view_benchmark.cc index f4420320..46909cb0 100644 --- a/absl/strings/string_view_benchmark.cc +++ b/absl/strings/string_view_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/string_view_test.cc b/absl/strings/string_view_test.cc index 2150b4e5..d439900d 100644 --- a/absl/strings/string_view_test.cc +++ b/absl/strings/string_view_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/strip.h b/absl/strings/strip.h index 8d0d7c6b..e1341e08 100644 --- a/absl/strings/strip.h +++ b/absl/strings/strip.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/strip_test.cc b/absl/strings/strip_test.cc index 67355fcb..e4e00cb6 100644 --- a/absl/strings/strip_test.cc +++ b/absl/strings/strip_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/substitute.cc b/absl/strings/substitute.cc index 3b200594..bc176950 100644 --- a/absl/strings/substitute.cc +++ b/absl/strings/substitute.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/substitute.h b/absl/strings/substitute.h index 2b74b382..a45ff039 100644 --- a/absl/strings/substitute.h +++ b/absl/strings/substitute.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/strings/substitute_test.cc b/absl/strings/substitute_test.cc index 144df01e..f6568906 100644 --- a/absl/strings/substitute_test.cc +++ b/absl/strings/substitute_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 43680046..ac019041 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index cb77b685..68473b73 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/barrier.cc b/absl/synchronization/barrier.cc index a1b3ad5c..c2c539ac 100644 --- a/absl/synchronization/barrier.cc +++ b/absl/synchronization/barrier.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/barrier.h b/absl/synchronization/barrier.h index f834feec..23bb2f58 100644 --- a/absl/synchronization/barrier.h +++ b/absl/synchronization/barrier.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/barrier_test.cc b/absl/synchronization/barrier_test.cc index d6cababd..bfc6cb18 100644 --- a/absl/synchronization/barrier_test.cc +++ b/absl/synchronization/barrier_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/blocking_counter.cc b/absl/synchronization/blocking_counter.cc index 7e68e960..481a06b2 100644 --- a/absl/synchronization/blocking_counter.cc +++ b/absl/synchronization/blocking_counter.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/blocking_counter.h b/absl/synchronization/blocking_counter.h index 557ed028..4c66e0ab 100644 --- a/absl/synchronization/blocking_counter.h +++ b/absl/synchronization/blocking_counter.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/blocking_counter_test.cc b/absl/synchronization/blocking_counter_test.cc index e8223f84..c63e3392 100644 --- a/absl/synchronization/blocking_counter_test.cc +++ b/absl/synchronization/blocking_counter_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/create_thread_identity.cc b/absl/synchronization/internal/create_thread_identity.cc index 60be25c9..6e93605d 100644 --- a/absl/synchronization/internal/create_thread_identity.cc +++ b/absl/synchronization/internal/create_thread_identity.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/create_thread_identity.h b/absl/synchronization/internal/create_thread_identity.h index 1bb87dee..b2525b72 100644 --- a/absl/synchronization/internal/create_thread_identity.h +++ b/absl/synchronization/internal/create_thread_identity.h @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/graphcycles.cc b/absl/synchronization/internal/graphcycles.cc index d3878de2..0c8c7564 100644 --- a/absl/synchronization/internal/graphcycles.cc +++ b/absl/synchronization/internal/graphcycles.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/graphcycles.h b/absl/synchronization/internal/graphcycles.h index 2e6686a4..e5bde007 100644 --- a/absl/synchronization/internal/graphcycles.h +++ b/absl/synchronization/internal/graphcycles.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/graphcycles_benchmark.cc b/absl/synchronization/internal/graphcycles_benchmark.cc index a239c25c..54823e0b 100644 --- a/absl/synchronization/internal/graphcycles_benchmark.cc +++ b/absl/synchronization/internal/graphcycles_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/graphcycles_test.cc b/absl/synchronization/internal/graphcycles_test.cc index 9a85b390..58e8477b 100644 --- a/absl/synchronization/internal/graphcycles_test.cc +++ b/absl/synchronization/internal/graphcycles_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/kernel_timeout.h b/absl/synchronization/internal/kernel_timeout.h index 9e1eed75..543c4a03 100644 --- a/absl/synchronization/internal/kernel_timeout.h +++ b/absl/synchronization/internal/kernel_timeout.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/mutex_nonprod.cc b/absl/synchronization/internal/mutex_nonprod.cc index 45c60326..267deaff 100644 --- a/absl/synchronization/internal/mutex_nonprod.cc +++ b/absl/synchronization/internal/mutex_nonprod.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc index caa2baf6..d22539dc 100644 --- a/absl/synchronization/internal/per_thread_sem.cc +++ b/absl/synchronization/internal/per_thread_sem.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/per_thread_sem.h b/absl/synchronization/internal/per_thread_sem.h index 678b69e4..d373f63b 100644 --- a/absl/synchronization/internal/per_thread_sem.h +++ b/absl/synchronization/internal/per_thread_sem.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/per_thread_sem_test.cc b/absl/synchronization/internal/per_thread_sem_test.cc index 8a318a51..dba72390 100644 --- a/absl/synchronization/internal/per_thread_sem_test.cc +++ b/absl/synchronization/internal/per_thread_sem_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/thread_pool.h b/absl/synchronization/internal/thread_pool.h index c753a68d..7f458f5a 100644 --- a/absl/synchronization/internal/thread_pool.h +++ b/absl/synchronization/internal/thread_pool.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/waiter.cc b/absl/synchronization/internal/waiter.cc index 768c5208..bab6d1a1 100644 --- a/absl/synchronization/internal/waiter.cc +++ b/absl/synchronization/internal/waiter.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/internal/waiter.h b/absl/synchronization/internal/waiter.h index 23166f4b..66b4bebf 100644 --- a/absl/synchronization/internal/waiter.h +++ b/absl/synchronization/internal/waiter.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 8b168e21..0279c8f8 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 40ab7d22..f4ed0d00 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 4b65e92c..cf0f86dc 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/mutex_benchmark.cc b/absl/synchronization/mutex_benchmark.cc index 2652bb97..ab188001 100644 --- a/absl/synchronization/mutex_benchmark.cc +++ b/absl/synchronization/mutex_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc index 92fcd53d..53c1f744 100644 --- a/absl/synchronization/mutex_test.cc +++ b/absl/synchronization/mutex_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index cdcbc134..53ace008 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/notification.h b/absl/synchronization/notification.h index f95f4d14..19f51de7 100644 --- a/absl/synchronization/notification.h +++ b/absl/synchronization/notification.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/synchronization/notification_test.cc b/absl/synchronization/notification_test.cc index 95bde0bd..059d4cd2 100644 --- a/absl/synchronization/notification_test.cc +++ b/absl/synchronization/notification_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/BUILD.bazel b/absl/time/BUILD.bazel index 578dc917..a94be655 100644 --- a/absl/time/BUILD.bazel +++ b/absl/time/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/CMakeLists.txt b/absl/time/CMakeLists.txt index db60e712..d67a486d 100644 --- a/absl/time/CMakeLists.txt +++ b/absl/time/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/civil_time.cc b/absl/time/civil_time.cc index c7ba8916..7527fc11 100644 --- a/absl/time/civil_time.cc +++ b/absl/time/civil_time.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/civil_time.h b/absl/time/civil_time.h index fd7f1e85..f231e4f8 100644 --- a/absl/time/civil_time.h +++ b/absl/time/civil_time.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/civil_time_benchmark.cc b/absl/time/civil_time_benchmark.cc index f30f636d..40869835 100644 --- a/absl/time/civil_time_benchmark.cc +++ b/absl/time/civil_time_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc index dc83d7a9..b8d57135 100644 --- a/absl/time/civil_time_test.cc +++ b/absl/time/civil_time_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/clock.cc b/absl/time/clock.cc index 4863f643..fa0ed34d 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/clock.h b/absl/time/clock.h index 3753d4ee..bb52e4f6 100644 --- a/absl/time/clock.h +++ b/absl/time/clock.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/clock_benchmark.cc b/absl/time/clock_benchmark.cc index 3d3cd9d5..a69fe00b 100644 --- a/absl/time/clock_benchmark.cc +++ b/absl/time/clock_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/clock_test.cc b/absl/time/clock_test.cc index 707166d0..4bcfc6bc 100644 --- a/absl/time/clock_test.cc +++ b/absl/time/clock_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/duration.cc b/absl/time/duration.cc index 7d4af8c7..be4ef2ea 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -749,7 +749,7 @@ void AppendNumberUnit(std::string* out, double n, DisplayUnit unit) { } // namespace -// From Go's doc at http://golang.org/pkg/time/#Duration.String +// From Go's doc at https://golang.org/pkg/time/#Duration.String // [FormatDuration] returns a string representing the duration in the // form "72h3m0.5s". Leading zero units are omitted. As a special // case, durations less than one second format use a smaller unit @@ -855,8 +855,8 @@ bool ConsumeDurationUnit(const char** start, Duration* unit) { } // namespace -// From Go's doc at http://golang.org/pkg/time/#ParseDuration -// [ParseDuration] parses a duration string. A duration string is +// From Go's doc at https://golang.org/pkg/time/#ParseDuration +// [ParseDuration] parses a duration string. A duration string is // a possibly signed sequence of decimal numbers, each with optional // fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". // Valid time units are "ns", "us" "ms", "s", "m", "h". diff --git a/absl/time/duration_benchmark.cc b/absl/time/duration_benchmark.cc index f5fcdfb8..83a836c8 100644 --- a/absl/time/duration_benchmark.cc +++ b/absl/time/duration_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 6dc307a9..e3cede6e 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/format.cc b/absl/time/format.cc index a3671510..d6ca8600 100644 --- a/absl/time/format.cc +++ b/absl/time/format.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/format_benchmark.cc b/absl/time/format_benchmark.cc index 766f1b39..249c51d8 100644 --- a/absl/time/format_benchmark.cc +++ b/absl/time/format_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/format_test.cc b/absl/time/format_test.cc index 46b972e6..4a1f1aa2 100644 --- a/absl/time/format_test.cc +++ b/absl/time/format_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/internal/get_current_time_chrono.inc b/absl/time/internal/get_current_time_chrono.inc index cf884a10..5180230d 100644 --- a/absl/time/internal/get_current_time_chrono.inc +++ b/absl/time/internal/get_current_time_chrono.inc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/internal/test_util.cc b/absl/time/internal/test_util.cc index 4483f2a9..59166a7c 100644 --- a/absl/time/internal/test_util.cc +++ b/absl/time/internal/test_util.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/internal/test_util.h b/absl/time/internal/test_util.h index d9940293..d7319ea8 100644 --- a/absl/time/internal/test_util.h +++ b/absl/time/internal/test_util.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/time.cc b/absl/time/time.cc index ac2c8a83..799bf859 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/time.h b/absl/time/time.h index 45df1fc7..fef305c5 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/time_benchmark.cc b/absl/time/time_benchmark.cc index 9bbed6f8..99e62799 100644 --- a/absl/time/time_benchmark.cc +++ b/absl/time/time_benchmark.cc @@ -3,7 +3,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index 4d710709..74148d58 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/time/time_zone_test.cc b/absl/time/time_zone_test.cc index 43d91904..8f1e74ac 100644 --- a/absl/time/time_zone_test.cc +++ b/absl/time/time_zone_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index 2e490009..7da00030 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt index 05097d9e..8afde466 100644 --- a/absl/types/CMakeLists.txt +++ b/absl/types/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/any.h b/absl/types/any.h index a973c6da..e750f485 100644 --- a/absl/types/any.h +++ b/absl/types/any.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/any_exception_safety_test.cc b/absl/types/any_exception_safety_test.cc index f9dd8c48..00d0fb72 100644 --- a/absl/types/any_exception_safety_test.cc +++ b/absl/types/any_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/any_test.cc b/absl/types/any_test.cc index 115e78df..a6351bf9 100644 --- a/absl/types/any_test.cc +++ b/absl/types/any_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/bad_any_cast.cc b/absl/types/bad_any_cast.cc index 2e2fd29a..505919a5 100644 --- a/absl/types/bad_any_cast.cc +++ b/absl/types/bad_any_cast.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/bad_any_cast.h b/absl/types/bad_any_cast.h index 60390132..8d020ede 100644 --- a/absl/types/bad_any_cast.h +++ b/absl/types/bad_any_cast.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/bad_optional_access.cc b/absl/types/bad_optional_access.cc index 55870776..a791c7c2 100644 --- a/absl/types/bad_optional_access.cc +++ b/absl/types/bad_optional_access.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/bad_optional_access.h b/absl/types/bad_optional_access.h index c6c27460..add5c452 100644 --- a/absl/types/bad_optional_access.h +++ b/absl/types/bad_optional_access.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/bad_variant_access.cc b/absl/types/bad_variant_access.cc index d27d7756..a4325c8d 100644 --- a/absl/types/bad_variant_access.cc +++ b/absl/types/bad_variant_access.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/bad_variant_access.h b/absl/types/bad_variant_access.h index e7355a5a..637db435 100644 --- a/absl/types/bad_variant_access.h +++ b/absl/types/bad_variant_access.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h index a0ab1e8f..4926b321 100644 --- a/absl/types/internal/variant.h +++ b/absl/types/internal/variant.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/optional.cc b/absl/types/optional.cc index ef272904..44ff8294 100644 --- a/absl/types/optional.cc +++ b/absl/types/optional.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/optional.h b/absl/types/optional.h index d800ca68..0c1213f4 100644 --- a/absl/types/optional.h +++ b/absl/types/optional.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/optional_exception_safety_test.cc b/absl/types/optional_exception_safety_test.cc index d117ee51..aaf8ebcd 100644 --- a/absl/types/optional_exception_safety_test.cc +++ b/absl/types/optional_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index cdbf1404..b93aa98e 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/span.h b/absl/types/span.h index a445f7af..bce18ebc 100644 --- a/absl/types/span.h +++ b/absl/types/span.h @@ -5,7 +5,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/span_test.cc b/absl/types/span_test.cc index ae71ebc2..294229ea 100644 --- a/absl/types/span_test.cc +++ b/absl/types/span_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/variant.h b/absl/types/variant.h index 48c5d7bf..9652e3b9 100644 --- a/absl/types/variant.h +++ b/absl/types/variant.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/variant_benchmark.cc b/absl/types/variant_benchmark.cc index 99658ac7..a5f52164 100644 --- a/absl/types/variant_benchmark.cc +++ b/absl/types/variant_benchmark.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/variant_exception_safety_test.cc b/absl/types/variant_exception_safety_test.cc index 82425dbd..086fcff0 100644 --- a/absl/types/variant_exception_safety_test.cc +++ b/absl/types/variant_exception_safety_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/types/variant_test.cc b/absl/types/variant_test.cc index c18cb77a..9df702df 100644 --- a/absl/types/variant_test.cc +++ b/absl/types/variant_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/utility/CMakeLists.txt b/absl/utility/CMakeLists.txt index 7fe34a5b..e1edd19a 100644 --- a/absl/utility/CMakeLists.txt +++ b/absl/utility/CMakeLists.txt @@ -5,7 +5,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/absl/utility/utility.h b/absl/utility/utility.h index 741b1f81..62ce6f3a 100644 --- a/absl/utility/utility.h +++ b/absl/utility/utility.h @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -32,8 +32,8 @@ // // References: // -// http://en.cppreference.com/w/cpp/utility/integer_sequence -// http://en.cppreference.com/w/cpp/utility/apply +// https://en.cppreference.com/w/cpp/utility/integer_sequence +// https://en.cppreference.com/w/cpp/utility/apply // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html // diff --git a/absl/utility/utility_test.cc b/absl/utility/utility_test.cc index 7f425fc7..5a4972b6 100644 --- a/absl/utility/utility_test.cc +++ b/absl/utility/utility_test.cc @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, -- cgit v1.2.3 From c6c3c1b498e4ee939b24be59cae29d59c3863be8 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 17 Jul 2019 16:35:47 -0400 Subject: Export of internal Abseil changes. -- ed3a3431eee9e48e6553b0320e0308d2dde6725c by Derek Mauro : Project import generated by Copybara. PiperOrigin-RevId: 258631680 GitOrigin-RevId: ed3a3431eee9e48e6553b0320e0308d2dde6725c Change-Id: I1d7ae86a79783842092d29504605ba039c369603 --- absl/base/spinlock_test_common.cc | 2 +- absl/container/BUILD.bazel | 3 + absl/container/CMakeLists.txt | 3 + absl/container/internal/common.h | 23 +- absl/container/internal/compressed_tuple.h | 49 ++- absl/container/internal/compressed_tuple_test.cc | 201 ++++++++++ absl/container/internal/hashtablez_sampler.cc | 2 +- absl/container/internal/raw_hash_set.h | 2 +- absl/container/internal/test_instance_tracker.h | 2 +- absl/flags/BUILD.bazel | 23 +- absl/flags/CMakeLists.txt | 21 +- absl/flags/flag.cc | 26 +- absl/flags/flag.h | 51 +-- absl/flags/internal/commandlineflag.cc | 439 +++++++++++++-------- absl/flags/internal/commandlineflag.h | 76 ++-- absl/flags/internal/commandlineflag_test.cc | 14 +- absl/flags/internal/flag.h | 72 ++-- absl/flags/internal/registry.cc | 54 ++- absl/flags/internal/type_erased.cc | 19 +- absl/flags/internal/usage.cc | 38 +- absl/flags/internal/usage.h | 7 +- absl/flags/internal/usage_test.cc | 38 +- absl/flags/parse.cc | 25 +- absl/hash/hash_test.cc | 1 - absl/hash/internal/hash.h | 3 +- absl/numeric/int128.h | 4 +- absl/random/internal/fast_uniform_bits.h | 349 ++++++++-------- absl/random/internal/fast_uniform_bits_test.cc | 241 ++++++++--- absl/strings/str_join.h | 5 +- .../internal/create_thread_identity.cc | 3 +- absl/time/time.h | 5 +- ci/linux_clang-latest_libcxx_asan_bazel.sh | 8 + 32 files changed, 1160 insertions(+), 649 deletions(-) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index e62b2eae..84fc4dac 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc @@ -62,7 +62,6 @@ static SpinLock static_cooperative_spinlock( static SpinLock static_noncooperative_spinlock( base_internal::kLinkerInitialized, base_internal::SCHEDULE_KERNEL_ONLY); - // Simple integer hash function based on the public domain lookup2 hash. // http://burtleburtle.net/bob/c/lookup2.c static uint32_t Hash32(uint32_t a, uint32_t c) { @@ -194,6 +193,7 @@ TEST(SpinLock, WaitCyclesEncoding) { TEST(SpinLockWithThreads, StaticSpinLock) { ThreadedTest(&static_spinlock); } + TEST(SpinLockWithThreads, StackSpinLock) { SpinLock spinlock; ThreadedTest(&spinlock); diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 17d725c1..b8cf17fc 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -44,7 +44,10 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":compressed_tuple", + ":test_instance_tracker", "//absl/memory", + "//absl/types:any", + "//absl/types:optional", "//absl/utility", "@com_google_googletest//:gtest_main", ], diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 6df331e1..5d7c75dd 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -43,8 +43,11 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS + absl::any absl::compressed_tuple absl::memory + absl::optional + absl::test_instance_tracker absl::utility gmock_main ) diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h index b06e7113..591d3ea1 100644 --- a/absl/container/internal/common.h +++ b/absl/container/internal/common.h @@ -77,10 +77,18 @@ class node_handle_base { protected: friend struct CommonAccess; - node_handle_base(const allocator_type& a, slot_type* s) : alloc_(a) { + struct transfer_tag_t {}; + node_handle_base(transfer_tag_t, const allocator_type& a, slot_type* s) + : alloc_(a) { PolicyTraits::transfer(alloc(), slot(), s); } + struct move_tag_t {}; + node_handle_base(move_tag_t, const allocator_type& a, slot_type* s) + : alloc_(a) { + PolicyTraits::construct(alloc(), slot(), s); + } + void destroy() { if (!empty()) { PolicyTraits::destroy(alloc(), slot()); @@ -121,7 +129,7 @@ class node_handle : public node_handle_base { private: friend struct CommonAccess; - node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {} + using Base::Base; }; // For maps. @@ -148,7 +156,7 @@ class node_handle - static T Make(Args&&... args) { - return T(std::forward(args)...); + static T Transfer(Args&&... args) { + return T(typename T::transfer_tag_t{}, std::forward(args)...); + } + + template + static T Move(Args&&... args) { + return T(typename T::move_tag_t{}, std::forward(args)...); } }; diff --git a/absl/container/internal/compressed_tuple.h b/absl/container/internal/compressed_tuple.h index c29ab41e..7d08e370 100644 --- a/absl/container/internal/compressed_tuple.h +++ b/absl/container/internal/compressed_tuple.h @@ -102,7 +102,9 @@ template (v)) {} + template + explicit constexpr Storage(absl::in_place_t, V&& v) + : value(absl::forward(v)) {} constexpr const T& get() const& { return value; } T& get() & { return value; } constexpr const T&& get() const&& { return absl::move(*this).value; } @@ -112,7 +114,11 @@ struct Storage { template struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage : T { constexpr Storage() = default; - explicit constexpr Storage(T&& v) : T(absl::forward(v)) {} + + template + explicit constexpr Storage(absl::in_place_t, V&& v) + : T(absl::forward(v)) {} + constexpr const T& get() const& { return *this; } T& get() & { return *this; } constexpr const T&& get() const&& { return absl::move(*this); } @@ -132,8 +138,9 @@ struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl< : uses_inheritance, Storage::value>... { constexpr CompressedTupleImpl() = default; - explicit constexpr CompressedTupleImpl(Ts&&... args) - : Storage(absl::forward(args))... {} + template + explicit constexpr CompressedTupleImpl(absl::in_place_t, Vs&&... args) + : Storage(absl::in_place, absl::forward(args))... {} friend CompressedTuple; }; @@ -143,8 +150,9 @@ struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl< // We use the dummy identity function as above... : Storage::value, false>... { constexpr CompressedTupleImpl() = default; - explicit constexpr CompressedTupleImpl(Ts&&... args) - : Storage(absl::forward(args))... {} + template + explicit constexpr CompressedTupleImpl(absl::in_place_t, Vs&&... args) + : Storage(absl::in_place, absl::forward(args))... {} friend CompressedTuple; }; @@ -159,6 +167,11 @@ constexpr bool ShouldAnyUseBase() { Or({std::integral_constant()>()...})){}; } +template +using TupleMoveConstructible = typename std::conditional< + std::is_reference::value, std::is_convertible, + std::is_constructible>::type; + } // namespace internal_compressed_tuple // Helper class to perform the Empty Base Class Optimization. @@ -192,9 +205,29 @@ class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple using StorageT = internal_compressed_tuple::Storage, I>; public: + // There seems to be a bug in MSVC dealing in which using '=default' here will + // cause the compiler to ignore the body of other constructors. The work- + // around is to explicitly implement the default constructor. +#if defined(_MSC_VER) + constexpr CompressedTuple() : CompressedTuple::CompressedTupleImpl() {} +#else constexpr CompressedTuple() = default; - explicit constexpr CompressedTuple(Ts... base) - : CompressedTuple::CompressedTupleImpl(absl::forward(base)...) {} +#endif + explicit constexpr CompressedTuple(const Ts&... base) + : CompressedTuple::CompressedTupleImpl(absl::in_place, base...) {} + + template ...)>>, + internal_compressed_tuple::TupleMoveConstructible< + Ts, Vs&&>...>::value, + bool> = true> + explicit constexpr CompressedTuple(Vs&&... base) + : CompressedTuple::CompressedTupleImpl(absl::in_place, + absl::forward(base)...) {} template ElemT& get() & { diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc index 3b0ec455..19af8f10 100644 --- a/absl/container/internal/compressed_tuple_test.cc +++ b/absl/container/internal/compressed_tuple_test.cc @@ -19,7 +19,10 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "absl/container/internal/test_instance_tracker.h" #include "absl/memory/memory.h" +#include "absl/types/any.h" +#include "absl/types/optional.h" #include "absl/utility/utility.h" // These are declared at global scope purely so that error messages @@ -43,10 +46,14 @@ struct TwoValues { U value2; }; + namespace absl { namespace container_internal { namespace { +using absl::test_internal::CopyableMovableInstance; +using absl::test_internal::InstanceTracker; + TEST(CompressedTupleTest, Sizeof) { EXPECT_EQ(sizeof(int), sizeof(CompressedTuple)); EXPECT_EQ(sizeof(int), sizeof(CompressedTuple>)); @@ -62,6 +69,141 @@ TEST(CompressedTupleTest, Sizeof) { sizeof(CompressedTuple, NotEmpty, Empty<1>>)); } +TEST(CompressedTupleTest, OneMoveOnRValueConstructionTemp) { + InstanceTracker tracker; + CompressedTuple x1(CopyableMovableInstance(1)); + EXPECT_EQ(tracker.instances(), 1); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_LE(tracker.moves(), 1); + EXPECT_EQ(x1.get<0>().value(), 1); +} + +TEST(CompressedTupleTest, OneMoveOnRValueConstructionMove) { + InstanceTracker tracker; + + CopyableMovableInstance i1(1); + CompressedTuple x1(std::move(i1)); + EXPECT_EQ(tracker.instances(), 2); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_LE(tracker.moves(), 1); + EXPECT_EQ(x1.get<0>().value(), 1); +} + +TEST(CompressedTupleTest, OneMoveOnRValueConstructionMixedTypes) { + InstanceTracker tracker; + CopyableMovableInstance i1(1); + CopyableMovableInstance i2(2); + Empty<0> empty; + CompressedTuple> + x1(std::move(i1), i2, empty); + EXPECT_EQ(x1.get<0>().value(), 1); + EXPECT_EQ(x1.get<1>().value(), 2); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 1); +} + +struct IncompleteType; +CompressedTuple> +MakeWithIncomplete(CopyableMovableInstance i1, + IncompleteType& t, // NOLINT + Empty<0> empty) { + return CompressedTuple>{ + std::move(i1), t, empty}; +} + +struct IncompleteType {}; +TEST(CompressedTupleTest, OneMoveOnRValueConstructionWithIncompleteType) { + InstanceTracker tracker; + CopyableMovableInstance i1(1); + Empty<0> empty; + struct DerivedType : IncompleteType {int value = 0;}; + DerivedType fd; + fd.value = 7; + + CompressedTuple> x1 = + MakeWithIncomplete(std::move(i1), fd, empty); + + EXPECT_EQ(x1.get<0>().value(), 1); + EXPECT_EQ(static_cast(x1.get<1>()).value, 7); + + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 2); +} + +TEST(CompressedTupleTest, + OneMoveOnRValueConstructionMixedTypes_BraceInitPoisonPillExpected) { + InstanceTracker tracker; + CopyableMovableInstance i1(1); + CopyableMovableInstance i2(2); + CompressedTuple> + x1(std::move(i1), i2, {}); // NOLINT + EXPECT_EQ(x1.get<0>().value(), 1); + EXPECT_EQ(x1.get<1>().value(), 2); + EXPECT_EQ(tracker.instances(), 3); + // We are forced into the `const Ts&...` constructor (invoking copies) + // because we need it to deduce the type of `{}`. + // std::tuple also has this behavior. + // Note, this test is proof that this is expected behavior, but it is not + // _desired_ behavior. + EXPECT_EQ(tracker.copies(), 1); + EXPECT_EQ(tracker.moves(), 0); +} + +TEST(CompressedTupleTest, OneCopyOnLValueConstruction) { + InstanceTracker tracker; + CopyableMovableInstance i1(1); + + CompressedTuple x1(i1); + EXPECT_EQ(tracker.copies(), 1); + EXPECT_EQ(tracker.moves(), 0); + + tracker.ResetCopiesMovesSwaps(); + + CopyableMovableInstance i2(2); + const CopyableMovableInstance& i2_ref = i2; + CompressedTuple x2(i2_ref); + EXPECT_EQ(tracker.copies(), 1); + EXPECT_EQ(tracker.moves(), 0); +} + +TEST(CompressedTupleTest, OneMoveOnRValueAccess) { + InstanceTracker tracker; + CopyableMovableInstance i1(1); + CompressedTuple x(std::move(i1)); + tracker.ResetCopiesMovesSwaps(); + + CopyableMovableInstance i2 = std::move(x).get<0>(); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 1); +} + +TEST(CompressedTupleTest, OneCopyOnLValueAccess) { + InstanceTracker tracker; + + CompressedTuple x(CopyableMovableInstance(0)); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 1); + + CopyableMovableInstance t = x.get<0>(); + EXPECT_EQ(tracker.copies(), 1); + EXPECT_EQ(tracker.moves(), 1); +} + +TEST(CompressedTupleTest, ZeroCopyOnRefAccess) { + InstanceTracker tracker; + + CompressedTuple x(CopyableMovableInstance(0)); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 1); + + CopyableMovableInstance& t1 = x.get<0>(); + const CopyableMovableInstance& t2 = x.get<0>(); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 1); + EXPECT_EQ(t1.value(), 0); + EXPECT_EQ(t2.value(), 0); +} + TEST(CompressedTupleTest, Access) { struct S { std::string x; @@ -173,7 +315,40 @@ TEST(CompressedTupleTest, MoveOnlyElements) { EXPECT_EQ(*x1, 5); } +TEST(CompressedTupleTest, MoveConstructionMoveOnlyElements) { + CompressedTuple> base( + absl::make_unique("str")); + EXPECT_EQ(*base.get<0>(), "str"); + + CompressedTuple> copy(std::move(base)); + EXPECT_EQ(*copy.get<0>(), "str"); +} + +TEST(CompressedTupleTest, AnyElements) { + any a(std::string("str")); + CompressedTuple x(any(5), a); + EXPECT_EQ(absl::any_cast(x.get<0>()), 5); + EXPECT_EQ(absl::any_cast(x.get<1>()), "str"); + + 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) { + struct NonTrivialStruct { + constexpr NonTrivialStruct() = default; + constexpr int value() const { return v; } + int v = 5; + }; + struct TrivialStruct { + TrivialStruct() = default; + constexpr int value() const { return v; } + int v; + }; constexpr CompressedTuple, Empty<0>> x( 7, 1.25, CompressedTuple(5), {}); constexpr int x0 = x.get<0>(); @@ -186,6 +361,32 @@ TEST(CompressedTupleTest, Constexpr) { EXPECT_EQ(x2, 5); EXPECT_EQ(x3, CallType::kConstRef); +#if !defined(__GNUC__) || defined(__clang__) || __GNUC__ > 4 + constexpr CompressedTuple, TrivialStruct, int> trivial = {}; + constexpr CallType trivial0 = trivial.get<0>().value(); + constexpr int trivial1 = trivial.get<1>().value(); + constexpr int trivial2 = trivial.get<2>(); + + EXPECT_EQ(trivial0, CallType::kConstRef); + EXPECT_EQ(trivial1, 0); + EXPECT_EQ(trivial2, 0); +#endif + + constexpr CompressedTuple, NonTrivialStruct, absl::optional> + non_trivial = {}; + constexpr CallType non_trivial0 = non_trivial.get<0>().value(); + constexpr int non_trivial1 = non_trivial.get<1>().value(); + constexpr absl::optional non_trivial2 = non_trivial.get<2>(); + + EXPECT_EQ(non_trivial0, CallType::kConstRef); + EXPECT_EQ(non_trivial1, 5); + EXPECT_EQ(non_trivial2, absl::nullopt); + + static constexpr char data[] = "DEF"; + constexpr CompressedTuple z(data); + constexpr const char* z1 = z.get<0>(); + EXPECT_EQ(std::string(z1), std::string(data)); + #if defined(__clang__) // An apparent bug in earlier versions of gcc claims these are ambiguous. constexpr int x2m = absl::move(x.get<2>()).get<0>(); diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 6667d3ad..d03dd82e 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -32,7 +32,7 @@ constexpr int HashtablezInfo::kMaxStackDepth; namespace { ABSL_CONST_INIT std::atomic g_hashtablez_enabled{ - false + false }; ABSL_CONST_INIT std::atomic g_hashtablez_sample_parameter{1 << 10}; ABSL_CONST_INIT std::atomic g_hashtablez_max_samples{1 << 20}; diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index c4889cd4..656e9806 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -1182,7 +1182,7 @@ class raw_hash_set { node_type extract(const_iterator position) { auto node = - CommonAccess::Make(alloc_ref(), position.inner_.slot_); + CommonAccess::Transfer(alloc_ref(), position.inner_.slot_); erase_meta_only(position); return node; } diff --git a/absl/container/internal/test_instance_tracker.h b/absl/container/internal/test_instance_tracker.h index 3d4b2980..c4731dbe 100644 --- a/absl/container/internal/test_instance_tracker.h +++ b/absl/container/internal/test_instance_tracker.h @@ -23,7 +23,7 @@ namespace absl { namespace test_internal { -// A type that counts number of occurences of the type, the live occurrences of +// A type that counts number of occurrences of the type, the live occurrences of // the type, as well as the number of copies, moves, swaps, and comparisons that // have occurred on the type. This is used as a base class for the copyable, // copyable+movable, and movable types below that are used in actual tests. Use diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 82e6ffcf..2fe61eaa 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -155,14 +155,12 @@ cc_library( ) cc_library( - name = "usage", + name = "usage_internal", srcs = [ "internal/usage.cc", - "usage.cc", ], hdrs = [ "internal/usage.h", - "usage.h", ], copts = ABSL_DEFAULT_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, @@ -179,6 +177,23 @@ cc_library( ], ) +cc_library( + name = "usage", + srcs = [ + "usage.cc", + ], + hdrs = [ + "usage.h", + ], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":usage_internal", + "//absl/strings", + "//absl/synchronization", + ], +) + cc_library( name = "parse", srcs = ["parse.cc"], @@ -195,6 +210,7 @@ cc_library( ":internal", ":registry", ":usage", + ":usage_internal", "//absl/strings", "//absl/synchronization", ], @@ -360,6 +376,7 @@ cc_test( ":internal", ":parse", ":usage", + ":usage_internal", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index 9c936ecc..fa1d4e17 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -141,13 +141,11 @@ absl_cc_library( # Internal-only target, do not depend on directly. absl_cc_library( NAME - flags_usage + flags_usage_internal SRCS "internal/usage.cc" - "usage.cc" HDRS "internal/usage.h" - "usage.h" COPTS ${ABSL_DEFAULT_COPTS} LINKOPTS @@ -161,6 +159,23 @@ absl_cc_library( absl::synchronization ) +absl_cc_library( + NAME + flags_usage + SRCS + "usage.cc" + HDRS + "usage.h" + COPTS + ${ABSL_DEFAULT_COPTS} + LINKOPTS + ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::flags_usage_internal + absl::strings + absl::synchronization +) + absl_cc_library( NAME flags_parse diff --git a/absl/flags/flag.cc b/absl/flags/flag.cc index ba002edd..f16cc75e 100644 --- a/absl/flags/flag.cc +++ b/absl/flags/flag.cc @@ -24,24 +24,16 @@ namespace absl { // so in debug builds we always use the slower implementation, which always // validates the type. #ifndef NDEBUG -#define ABSL_FLAGS_ATOMIC_GET(T) \ - T GetFlag(const absl::Flag& flag) { \ - T result; \ - flag.internal.Read(&result, &flags_internal::FlagOps); \ - return result; \ - } +#define ABSL_FLAGS_ATOMIC_GET(T) \ + T GetFlag(const absl::Flag& flag) { return flag.Get(); } #else -#define ABSL_FLAGS_ATOMIC_GET(T) \ - T GetFlag(const absl::Flag& flag) { \ - const int64_t r = flag.internal.atomic.load(std::memory_order_acquire); \ - if (r != flags_internal::CommandLineFlag::kAtomicInit) { \ - T t; \ - memcpy(&t, &r, sizeof(T)); \ - return t; \ - } \ - T result; \ - flag.internal.Read(&result, &flags_internal::FlagOps); \ - return result; \ +#define ABSL_FLAGS_ATOMIC_GET(T) \ + T GetFlag(const absl::Flag& flag) { \ + T result; \ + if (flag.AtomicGet(&result)) { \ + return result; \ + } \ + return flag.Get(); \ } #endif diff --git a/absl/flags/flag.h b/absl/flags/flag.h index 193755e5..c70023ab 100644 --- a/absl/flags/flag.h +++ b/absl/flags/flag.h @@ -91,30 +91,7 @@ T GetFlag(const absl::Flag& flag) { ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(ABSL_FLAGS_INTERNAL_LOCK_FREE_VALIDATE) #undef ABSL_FLAGS_INTERNAL_LOCK_FREE_VALIDATE - // Implementation notes: - // - // We are wrapping a union around the value of `T` to serve three purposes: - // - // 1. `U.value` has correct size and alignment for a value of type `T` - // 2. The `U.value` constructor is not invoked since U's constructor does not - // do it explicitly. - // 3. The `U.value` destructor is invoked since U's destructor does it - // explicitly. This makes `U` a kind of RAII wrapper around non default - // constructible value of T, which is destructed when we leave the scope. - // We do need to destroy U.value, which is constructed by - // CommandLineFlag::Read even though we left it in a moved-from state - // after std::move. - // - // All of this serves to avoid requiring `T` being default constructible. - union U { - T value; - U() {} - ~U() { value.~T(); } - }; - U u; - - flag.internal.Read(&u.value, &flags_internal::FlagOps); - return std::move(u.value); + return flag.Get(); } // Overload for `GetFlag()` for types that support lock-free reads. @@ -132,7 +109,7 @@ ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(ABSL_FLAGS_INTERNAL_LOCK_FREE_EXPORT) // but especially within performance-critical code. template void SetFlag(absl::Flag* flag, const T& v) { - flag->internal.Write(&v, &flags_internal::FlagOps); + flag->Set(v); } // Overload of `SetFlag()` to allow callers to pass in a value that is @@ -141,7 +118,7 @@ void SetFlag(absl::Flag* flag, const T& v) { template void SetFlag(absl::Flag* flag, const V& v) { T value(v); - SetFlag(flag, value); + flag->Set(value); } } // namespace absl @@ -239,17 +216,17 @@ void SetFlag(absl::Flag* flag, const V& v) { // Note: Name of registrar object is not arbitrary. It is used to "grab" // global name for FLAGS_no symbol, thus preventing the possibility // of defining two flags with names foo and nofoo. -#define ABSL_FLAG_IMPL(Type, name, default_value, help) \ - namespace absl {} \ - ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ - ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \ - absl::Flag FLAGS_##name( \ - ABSL_FLAG_IMPL_FLAGNAME(#name), \ - &AbslFlagsWrapHelp##name, \ - ABSL_FLAG_IMPL_FILENAME(), \ - &absl::flags_internal::FlagMarshallingOps, \ - &AbslFlagsInitFlag##name); \ - extern bool FLAGS_no##name; \ +#define ABSL_FLAG_IMPL(Type, name, default_value, help) \ + namespace absl {} \ + ABSL_FLAG_IMPL_DECLARE_DEF_VAL_WRAPPER(name, Type, default_value) \ + ABSL_FLAG_IMPL_DECLARE_HELP_WRAPPER(name, help) \ + absl::Flag FLAGS_##name( \ + ABSL_FLAG_IMPL_FLAGNAME(#name), \ + &AbslFlagsWrapHelp##name, \ + ABSL_FLAG_IMPL_FILENAME(), \ + &absl::flags_internal::FlagMarshallingOps, \ + &AbslFlagsInitFlag##name); \ + extern bool FLAGS_no##name; \ bool FLAGS_no##name = ABSL_FLAG_IMPL_REGISTRAR(Type, FLAGS_##name) // ABSL_RETIRED_FLAG diff --git a/absl/flags/internal/commandlineflag.cc b/absl/flags/internal/commandlineflag.cc index 74444721..98a46695 100644 --- a/absl/flags/internal/commandlineflag.cc +++ b/absl/flags/internal/commandlineflag.cc @@ -37,44 +37,6 @@ const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001"; namespace { -void StoreAtomic(CommandLineFlag* flag, const void* data, size_t size) { - int64_t t = 0; - assert(size <= sizeof(int64_t)); - memcpy(&t, data, size); - flag->atomic.store(t, std::memory_order_release); -} - -// 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 -// re-locked back after call to callback is completed. Callback invocation is -// guarded by flag's secondary mutex instead which prevents concurrent callback -// invocation. Note that it is possible for other thread to grab the primary -// lock and update flag's value at any time during the callback invocation. -// This is by design. Callback can get a value of the flag if necessary, but it -// might be different from the value initiated the callback 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. -void InvokeCallback(CommandLineFlag* flag, absl::Mutex* primary_lock) - EXCLUSIVE_LOCKS_REQUIRED(primary_lock) { - if (!flag->callback) return; - - // The callback lock is guaranteed initialized, because *primary_lock exists. - absl::Mutex* callback_mu = &flag->locks->callback_mu; - - // When executing the callback we need the primary flag's mutex to be unlocked - // so that callback can retrieve the flag's value. - primary_lock->Unlock(); - - { - absl::MutexLock lock(callback_mu); - - flag->callback(); - } - - primary_lock->Lock(); -} - // Currently we only validate flag values for user-defined flag types. bool ShouldValidateFlagValue(const CommandLineFlag& flag) { #define DONT_VALIDATE(T) \ @@ -89,145 +51,72 @@ bool ShouldValidateFlagValue(const CommandLineFlag& flag) { } // namespace -// Update any copy of the flag value that is stored in an atomic word. -// In addition if flag has a mutation callback this function invokes it. -void UpdateCopy(CommandLineFlag* flag, absl::Mutex* primary_lock) - EXCLUSIVE_LOCKS_REQUIRED(primary_lock) { -#define STORE_ATOMIC(T) \ - else if (flag->IsOfType()) { \ - StoreAtomic(flag, flag->cur, sizeof(T)); \ - } - - if (false) { - } - ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(STORE_ATOMIC) -#undef STORE_ATOMIC +absl::Mutex* InitFlag(CommandLineFlag* flag) { + ABSL_CONST_INIT static absl::Mutex init_lock(absl::kConstInit); + absl::Mutex* mu; - InvokeCallback(flag, primary_lock); -} + { + absl::MutexLock lock(&init_lock); -// Ensure that the lazily initialized fields of *flag have been initialized, -// and return &flag->locks->primary_mu. -absl::Mutex* InitFlagIfNecessary(CommandLineFlag* flag) - LOCK_RETURNED(flag->locks->primary_mu) { - absl::Mutex* mu; - if (!flag->inited.load(std::memory_order_acquire)) { - // Need to initialize lazily initialized fields. - ABSL_CONST_INIT static absl::Mutex init_lock(absl::kConstInit); - init_lock.Lock(); if (flag->locks == nullptr) { // Must initialize Mutexes for this flag. flag->locks = new flags_internal::CommandLineFlagLocks; } + mu = &flag->locks->primary_mu; - init_lock.Unlock(); - mu->Lock(); - if (!flag->retired && - flag->def == nullptr) { // Need to initialize def and cur fields. + } + + { + absl::MutexLock lock(mu); + + if (!flag->retired && flag->def == nullptr) { + // Need to initialize def and cur fields. flag->def = (*flag->make_init_value)(); flag->cur = Clone(flag->op, flag->def); - UpdateCopy(flag, mu); + UpdateCopy(flag); + flag->inited.store(true, std::memory_order_release); + flag->InvokeCallback(); } - mu->Unlock(); - flag->inited.store(true, std::memory_order_release); - } else { // All fields initialized; flag->locks is therefore safe to read. - mu = &flag->locks->primary_mu; } + + flag->inited.store(true, std::memory_order_release); return mu; } -// Return true iff flag value was changed via direct-access. -bool ChangedDirectly(CommandLineFlag* flag, const void* a, const void* b) { - if (!flag->IsAbseilFlag()) { - // Need to compare values for direct-access flags. -#define CHANGED_FOR_TYPE(T) \ - if (flag->IsOfType()) { \ - return *reinterpret_cast(a) != *reinterpret_cast(b); \ +// Ensure that the lazily initialized fields of *flag have been initialized, +// and return &flag->locks->primary_mu. +absl::Mutex* CommandLineFlag::InitFlagIfNecessary() const + LOCK_RETURNED(locks->primary_mu) { + if (!this->inited.load(std::memory_order_acquire)) { + return InitFlag(const_cast(this)); } - CHANGED_FOR_TYPE(bool); - CHANGED_FOR_TYPE(int32_t); - CHANGED_FOR_TYPE(int64_t); - CHANGED_FOR_TYPE(uint64_t); - CHANGED_FOR_TYPE(double); - CHANGED_FOR_TYPE(std::string); -#undef CHANGED_FOR_TYPE - } - return false; + // All fields initialized; this->locks is therefore safe to read. + return &this->locks->primary_mu; } -// Direct-access flags can be modified without going through the -// flag API. Detect such changes and updated the modified bit. -void UpdateModifiedBit(CommandLineFlag* flag) { - if (!flag->IsAbseilFlag()) { - absl::MutexLock l(InitFlagIfNecessary(flag)); - if (!flag->modified && ChangedDirectly(flag, flag->cur, flag->def)) { - flag->modified = true; - } +void CommandLineFlag::Destroy() const { + // Values are heap allocated for retired and Abseil Flags. + if (IsRetired() || IsAbseilFlag()) { + if (this->cur) Delete(this->op, this->cur); + if (this->def) Delete(this->op, this->def); } -} -bool Validate(CommandLineFlag*, const void*) { - return true; + delete this->locks; } -std::string HelpText::GetHelpText() const { - if (help_function_) return help_function_(); - if (help_message_) return help_message_; - - return {}; +bool CommandLineFlag::IsModified() const { + absl::MutexLock l(InitFlagIfNecessary()); + return modified; } -const int64_t CommandLineFlag::kAtomicInit; - -void CommandLineFlag::Read(void* dst, - const flags_internal::FlagOpFn dst_op) const { - absl::ReaderMutexLock l( - InitFlagIfNecessary(const_cast(this))); - - // `dst_op` is the unmarshaling operation corresponding to the declaration - // visibile at the call site. `op` is the Flag's defined unmarshalling - // operation. They must match for this operation to be well-defined. - if (ABSL_PREDICT_FALSE(dst_op != op)) { - ABSL_INTERNAL_LOG( - ERROR, - absl::StrCat("Flag '", name, - "' is defined as one type and declared as another")); - } - CopyConstruct(op, cur, dst); +void CommandLineFlag::SetModified(bool is_modified) { + absl::MutexLock l(InitFlagIfNecessary()); + modified = is_modified; } -void CommandLineFlag::Write(const void* src, - const flags_internal::FlagOpFn src_op) { - absl::Mutex* mu = InitFlagIfNecessary(this); - absl::MutexLock l(mu); - - // `src_op` is the marshalling operation corresponding to the declaration - // visible at the call site. `op` is the Flag's defined marshalling operation. - // They must match for this operation to be well-defined. - if (ABSL_PREDICT_FALSE(src_op != op)) { - ABSL_INTERNAL_LOG( - ERROR, - absl::StrCat("Flag '", name, - "' is defined as one type and declared as another")); - } - - if (ShouldValidateFlagValue(*this)) { - void* obj = Clone(op, src); - std::string ignored_error; - std::string src_as_str = Unparse(marshalling_op, src); - if (!Parse(marshalling_op, src_as_str, obj, &ignored_error) || - !Validate(this, obj)) { - ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", name, - "' to invalid value ", src_as_str)); - } - Delete(op, obj); - } - - modified = true; - counter++; - Copy(op, src, cur); - - UpdateCopy(this, mu); +bool CommandLineFlag::IsSpecifiedOnCommandLine() const { + absl::MutexLock l(InitFlagIfNecessary()); + return on_command_line; } absl::string_view CommandLineFlag::Typename() const { @@ -259,21 +148,96 @@ std::string CommandLineFlag::Filename() const { } std::string CommandLineFlag::DefaultValue() const { + absl::MutexLock l(InitFlagIfNecessary()); + return Unparse(this->marshalling_op, this->def); } std::string CommandLineFlag::CurrentValue() const { + absl::MutexLock l(InitFlagIfNecessary()); + return Unparse(this->marshalling_op, this->cur); } +bool CommandLineFlag::HasValidatorFn() const { + absl::MutexLock l(InitFlagIfNecessary()); + + return this->validator != nullptr; +} + +bool CommandLineFlag::SetValidatorFn(FlagValidator fn) { + absl::MutexLock l(InitFlagIfNecessary()); + + // ok to register the same function over and over again + if (fn == this->validator) return true; + + // Can't set validator to a different function, unless reset first. + if (fn != nullptr && this->validator != nullptr) { + ABSL_INTERNAL_LOG( + WARNING, absl::StrCat("Ignoring SetValidatorFn() for flag '", Name(), + "': validate-fn already registered")); + + return false; + } + + this->validator = fn; + return true; +} + +bool CommandLineFlag::InvokeValidator(const void* value) const + EXCLUSIVE_LOCKS_REQUIRED(this->locks->primary_mu) { + if (!this->validator) { + return true; + } + + (void)value; + + ABSL_INTERNAL_LOG( + FATAL, + absl::StrCat("Flag '", Name(), + "' of encapsulated type should not have a validator")); + + return false; +} + void CommandLineFlag::SetCallback( const flags_internal::FlagCallback mutation_callback) { - absl::Mutex* mu = InitFlagIfNecessary(this); - absl::MutexLock l(mu); + absl::MutexLock l(InitFlagIfNecessary()); callback = mutation_callback; - InvokeCallback(this, mu); + InvokeCallback(); +} + +// 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 +// re-locked back after call to callback is completed. Callback invocation is +// guarded by flag's secondary mutex instead which prevents concurrent callback +// invocation. Note that it is possible for other thread to grab the primary +// lock and update flag's value at any time during the callback invocation. +// This is by design. Callback can get a value of the flag if necessary, but it +// might be different from the value initiated the callback 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. +void CommandLineFlag::InvokeCallback() + EXCLUSIVE_LOCKS_REQUIRED(this->locks->primary_mu) { + if (!this->callback) return; + + // The callback lock is guaranteed initialized, because *locks->primary_mu + // exists. + absl::Mutex* callback_mu = &this->locks->callback_mu; + + // When executing the callback we need the primary flag's mutex to be unlocked + // so that callback can retrieve the flag's value. + this->locks->primary_mu.Unlock(); + + { + absl::MutexLock lock(callback_mu); + this->callback(); + } + + this->locks->primary_mu.Lock(); } // Attempts to parse supplied `value` string using parsing routine in the `flag` @@ -282,8 +246,9 @@ void CommandLineFlag::SetCallback( // 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' -static bool TryParseLocked(CommandLineFlag* flag, void* dst, - absl::string_view value, std::string* err) { +bool TryParseLocked(CommandLineFlag* flag, void* dst, absl::string_view value, + std::string* err) + EXCLUSIVE_LOCKS_REQUIRED(flag->locks->primary_mu) { void* tentative_value = Clone(flag->op, flag->def); std::string parse_err; if (!Parse(flag->marshalling_op, value, tentative_value, &parse_err)) { @@ -297,7 +262,7 @@ static bool TryParseLocked(CommandLineFlag* flag, void* dst, return false; } - if (!Validate(flag, tentative_value)) { + if (!flag->InvokeValidator(tentative_value)) { *err = absl::StrCat("Failed validation of new value '", Unparse(flag->marshalling_op, tentative_value), "' for flag '", flag->Name(), "'"); @@ -324,17 +289,23 @@ bool CommandLineFlag::SetFromString(absl::string_view value, ValueSource source, std::string* err) { if (IsRetired()) return false; - UpdateModifiedBit(this); + absl::MutexLock l(InitFlagIfNecessary()); - absl::Mutex* mu = InitFlagIfNecessary(this); - absl::MutexLock l(mu); + // Direct-access flags can be modified without going through the + // flag API. Detect such changes and update the flag->modified bit. + if (!IsAbseilFlag()) { + if (!this->modified && ChangedDirectly(this, this->cur, this->def)) { + this->modified = true; + } + } switch (set_mode) { case SET_FLAGS_VALUE: { // set or modify the flag's value if (!TryParseLocked(this, this->cur, value, err)) return false; this->modified = true; - UpdateCopy(this, mu); + UpdateCopy(this); + InvokeCallback(); if (source == kCommandLine) { this->on_command_line = true; @@ -346,7 +317,8 @@ bool CommandLineFlag::SetFromString(absl::string_view value, if (!this->modified) { if (!TryParseLocked(this, this->cur, value, err)) return false; this->modified = true; - UpdateCopy(this, mu); + UpdateCopy(this); + InvokeCallback(); } else { // TODO(rogeeff): review and fix this semantic. Currently we do not fail // in this case if flag is modified. This is misleading since the flag's @@ -365,7 +337,8 @@ bool CommandLineFlag::SetFromString(absl::string_view value, if (!this->modified) { // Need to set both defvalue *and* current, in this case Copy(this->op, this->def, this->cur); - UpdateCopy(this, mu); + UpdateCopy(this); + InvokeCallback(); } break; } @@ -379,5 +352,143 @@ bool CommandLineFlag::SetFromString(absl::string_view value, return true; } +void CommandLineFlag::StoreAtomic(size_t size) { + int64_t t = 0; + assert(size <= sizeof(int64_t)); + memcpy(&t, this->cur, size); + this->atomic.store(t, std::memory_order_release); +} + +void CommandLineFlag::CheckDefaultValueParsingRoundtrip() const { + std::string v = DefaultValue(); + + absl::MutexLock lock(InitFlagIfNecessary()); + + void* dst = Clone(this->op, this->def); + std::string error; + if (!flags_internal::Parse(this->marshalling_op, v, dst, &error)) { + ABSL_INTERNAL_LOG( + FATAL, + absl::StrCat("Flag ", Name(), " (from ", Filename(), + "): std::string form of default value '", v, + "' could not be parsed; error=", error)); + } + + // We do not compare dst to def since parsing/unparsing may make + // small changes, e.g., precision loss for floating point types. + Delete(this->op, dst); +} + +bool CommandLineFlag::ValidateDefaultValue() const { + absl::MutexLock lock(InitFlagIfNecessary()); + return InvokeValidator(this->def); +} + +bool CommandLineFlag::ValidateInputValue(absl::string_view value) const { + absl::MutexLock l(InitFlagIfNecessary()); // protect default value access + + void* obj = Clone(this->op, this->def); + std::string ignored_error; + const bool result = + flags_internal::Parse(this->marshalling_op, value, obj, &ignored_error) && + InvokeValidator(obj); + Delete(this->op, obj); + return result; +} + +const int64_t CommandLineFlag::kAtomicInit; + +void CommandLineFlag::Read(void* dst, + const flags_internal::FlagOpFn dst_op) const { + absl::ReaderMutexLock l(InitFlagIfNecessary()); + + // `dst_op` is the unmarshaling operation corresponding to the declaration + // visibile at the call site. `op` is the Flag's defined unmarshalling + // operation. They must match for this operation to be well-defined. + if (ABSL_PREDICT_FALSE(dst_op != op)) { + ABSL_INTERNAL_LOG( + ERROR, + absl::StrCat("Flag '", name, + "' is defined as one type and declared as another")); + } + CopyConstruct(op, cur, dst); +} + +void CommandLineFlag::Write(const void* src, + const flags_internal::FlagOpFn src_op) { + absl::MutexLock l(InitFlagIfNecessary()); + + // `src_op` is the marshalling operation corresponding to the declaration + // visible at the call site. `op` is the Flag's defined marshalling operation. + // They must match for this operation to be well-defined. + if (ABSL_PREDICT_FALSE(src_op != op)) { + ABSL_INTERNAL_LOG( + ERROR, + absl::StrCat("Flag '", name, + "' is defined as one type and declared as another")); + } + + if (ShouldValidateFlagValue(*this)) { + void* obj = Clone(op, src); + std::string ignored_error; + std::string src_as_str = Unparse(marshalling_op, src); + if (!Parse(marshalling_op, src_as_str, obj, &ignored_error) || + !InvokeValidator(obj)) { + ABSL_INTERNAL_LOG(ERROR, absl::StrCat("Attempt to set flag '", name, + "' to invalid value ", src_as_str)); + } + Delete(op, obj); + } + + modified = true; + counter++; + Copy(op, src, cur); + + UpdateCopy(this); + InvokeCallback(); +} + +std::string HelpText::GetHelpText() const { + if (help_function_) return help_function_(); + if (help_message_) return help_message_; + + return {}; +} + +// Update any copy of the flag value that is stored in an atomic word. +// In addition if flag has a mutation callback this function invokes it. +void UpdateCopy(CommandLineFlag* flag) { +#define STORE_ATOMIC(T) \ + else if (flag->IsOfType()) { \ + flag->StoreAtomic(sizeof(T)); \ + } + + if (false) { + } + ABSL_FLAGS_INTERNAL_FOR_EACH_LOCK_FREE(STORE_ATOMIC) +#undef STORE_ATOMIC +} + +// Return true iff flag value was changed via direct-access. +bool ChangedDirectly(CommandLineFlag* flag, const void* a, const void* b) { + if (!flag->IsAbseilFlag()) { +// Need to compare values for direct-access flags. +#define CHANGED_FOR_TYPE(T) \ + if (flag->IsOfType()) { \ + return *reinterpret_cast(a) != *reinterpret_cast(b); \ + } + + CHANGED_FOR_TYPE(bool); + CHANGED_FOR_TYPE(int32_t); + CHANGED_FOR_TYPE(int64_t); + CHANGED_FOR_TYPE(uint64_t); + CHANGED_FOR_TYPE(double); + CHANGED_FOR_TYPE(std::string); +#undef CHANGED_FOR_TYPE + } + + return false; +} + } // namespace flags_internal } // namespace absl diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h index 4815cdc7..d82443a7 100644 --- a/absl/flags/internal/commandlineflag.h +++ b/absl/flags/internal/commandlineflag.h @@ -69,11 +69,15 @@ using HelpGenFunc = std::string (*)(); // based on default value supplied in flag's definition) using InitialValGenFunc = void* (*)(); +struct CommandLineFlagInfo; + // Signature for the mutation callback used by watched Flags // The callback is noexcept. // TODO(rogeeff): add noexcept after C++17 support is added. using FlagCallback = void (*)(); +using FlagValidator = bool (*)(); + extern const char kStrippedFlagHelp[]; // The per-type function @@ -217,6 +221,9 @@ struct CommandLineFlag { atomic(kAtomicInit), locks(nullptr) {} + // Revert the init routine. + void Destroy() const; + // Not copyable/assignable. CommandLineFlag(const CommandLineFlag&) = delete; CommandLineFlag& operator=(const CommandLineFlag&) = delete; @@ -224,7 +231,9 @@ struct CommandLineFlag { absl::string_view Name() const { return name; } std::string Help() const { return help.GetHelpText(); } bool IsRetired() const { return this->retired; } - bool IsSpecifiedOnCommandLine() const { return on_command_line; } + bool IsModified() const; + void SetModified(bool is_modified); + bool IsSpecifiedOnCommandLine() const; // Returns true iff this is a handle to an Abseil Flag. bool IsAbseilFlag() const { // Set to null for V1 flags @@ -236,6 +245,10 @@ struct CommandLineFlag { std::string DefaultValue() const; std::string CurrentValue() const; + bool HasValidatorFn() const; + bool SetValidatorFn(FlagValidator fn); + bool InvokeValidator(const void* value) const; + // Return true iff flag has type T. template inline bool IsOfType() const { @@ -245,7 +258,7 @@ struct CommandLineFlag { // Attempts to retrieve the flag value. Returns value on success, // absl::nullopt otherwise. template - absl::optional Get() { + absl::optional Get() const { if (IsRetired() || flags_internal::FlagOps != this->op) return absl::nullopt; @@ -256,6 +269,7 @@ struct CommandLineFlag { } void SetCallback(const flags_internal::FlagCallback mutation_callback); + void InvokeCallback(); // Sets the value of the flag based on specified std::string `value`. If the flag // was successfully set to new value, it returns true. Otherwise, sets `error` @@ -269,27 +283,35 @@ struct CommandLineFlag { flags_internal::FlagSettingMode set_mode, flags_internal::ValueSource source, std::string* error); + void StoreAtomic(size_t size); + + void CheckDefaultValueParsingRoundtrip() const; + // Invoke the flag validators for old flags. + // TODO(rogeeff): implement proper validators for Abseil Flags + bool ValidateDefaultValue() const; + bool ValidateInputValue(absl::string_view value) const; + // Constant configuration for a particular flag. private: const char* const name; const HelpText help; const char* const filename; - public: - const FlagOpFn op; // Type-specific handler + protected: + const FlagOpFn op; // Type-specific handler const FlagMarshallingOpFn marshalling_op; // Marshalling ops handler const InitialValGenFunc make_init_value; // Makes initial value for the flag - const bool retired; // Is the flag retired? - std::atomic inited; // fields have been lazily initialized + const bool retired; // Is the flag retired? + std::atomic inited; // fields have been lazily initialized // Mutable state (guarded by locks->primary_mu). - bool modified; // Has flag value been modified? - bool on_command_line; // Specified on command line. - bool (*validator)(); // Validator function, or nullptr - FlagCallback callback; // Mutation callback, or nullptr - void* def; // Lazily initialized pointer to default value - void* cur; // Lazily initialized pointer to current value - int64_t counter; // Mutation counter + bool modified; // Has flag value been modified? + bool on_command_line; // Specified on command line. + FlagValidator validator; // Validator function, or nullptr + FlagCallback callback; // Mutation callback, or nullptr + void* def; // Lazily initialized pointer to default value + void* cur; // Lazily initialized pointer to current value + int64_t counter; // Mutation counter // For some types, a copy of the current value is kept in an atomically // accessible field. @@ -302,24 +324,26 @@ struct CommandLineFlag { // TODO(rogeeff): fix it once Mutex has constexpr constructor struct CommandLineFlagLocks* locks; // locks, laziliy allocated. + // Ensure that the lazily initialized fields of *flag have been initialized, + // and return the lock which should be locked when flag's state is mutated. + absl::Mutex* InitFlagIfNecessary() const; + // copy construct new value of flag's type in a memory referenced by dst // based on current flag's value void Read(void* dst, const flags_internal::FlagOpFn dst_op) const; // updates flag's value to *src (locked) void Write(const void* src, const flags_internal::FlagOpFn src_op); - ABSL_DEPRECATED( - "temporary until FlagName call sites are migrated and validator API is " - "changed") - const char* NameAsCString() const { return name; } - - private: friend class FlagRegistry; + friend class FlagPtrMap; + friend class FlagSaverImpl; + friend void FillCommandLineFlagInfo(CommandLineFlag* flag, + CommandLineFlagInfo* result); + friend bool TryParseLocked(CommandLineFlag* flag, void* dst, + absl::string_view value, std::string* err); + friend absl::Mutex* InitFlag(CommandLineFlag* flag); }; -// Ensure that the lazily initialized fields of *flag have been initialized, -// and return &flag->locks->primary_mu. -absl::Mutex* InitFlagIfNecessary(CommandLineFlag* flag); // Update any copy of the flag value that is stored in an atomic word. // In addition if flag has a mutation callback this function invokes it. While // callback is being invoked the primary flag's mutex is unlocked and it is @@ -332,15 +356,9 @@ absl::Mutex* InitFlagIfNecessary(CommandLineFlag* flag); // 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. -void UpdateCopy(CommandLineFlag* flag, absl::Mutex* primary_lock); +void UpdateCopy(CommandLineFlag* flag); // Return true iff flag value was changed via direct-access. bool ChangedDirectly(CommandLineFlag* flag, const void* a, const void* b); -// Direct-access flags can be modified without going through the -// flag API. Detect such changes and updated the modified bit. -void UpdateModifiedBit(CommandLineFlag* flag); -// Invoke the flag validators for old flags. -// TODO(rogeeff): implement proper validators for Abseil Flags -bool Validate(CommandLineFlag* flag, const void* value); // This macro is the "source of truth" for the list of supported flag types we // expect to perform lock free operations on. Specifically it generates code, diff --git a/absl/flags/internal/commandlineflag_test.cc b/absl/flags/internal/commandlineflag_test.cc index 705f301c..f0d57adb 100644 --- a/absl/flags/internal/commandlineflag_test.cc +++ b/absl/flags/internal/commandlineflag_test.cc @@ -100,39 +100,39 @@ TEST_F(CommandLineFlagTest, TestSetFromStringCurrentValue) { std::string err; auto* flag_01 = flags::FindCommandLineFlag("int_flag"); - EXPECT_FALSE(flag_01->on_command_line); + EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); EXPECT_TRUE(flag_01->SetFromString("11", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11); - EXPECT_FALSE(flag_01->on_command_line); + EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); EXPECT_TRUE(flag_01->SetFromString("-123", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), -123); - EXPECT_FALSE(flag_01->on_command_line); + EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); EXPECT_TRUE(!flag_01->SetFromString("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(flag_01->on_command_line); + EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); EXPECT_TRUE(!flag_01->SetFromString("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(flag_01->on_command_line); + EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); EXPECT_TRUE(flag_01->SetFromString("0x10", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 16); - EXPECT_FALSE(flag_01->on_command_line); + EXPECT_FALSE(flag_01->IsSpecifiedOnCommandLine()); EXPECT_TRUE(flag_01->SetFromString("011", flags::SET_FLAGS_VALUE, flags::kCommandLine, &err)); EXPECT_EQ(absl::GetFlag(FLAGS_int_flag), 11); - EXPECT_TRUE(flag_01->on_command_line); + EXPECT_TRUE(flag_01->IsSpecifiedOnCommandLine()); EXPECT_TRUE(!flag_01->SetFromString("", flags::SET_FLAGS_VALUE, flags::kProgrammaticChange, &err)); diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 9b32f467..bc50de54 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h @@ -24,40 +24,58 @@ namespace flags_internal { // This is "unspecified" implementation of absl::Flag type. template -class Flag { +class Flag : public flags_internal::CommandLineFlag { public: constexpr Flag(const char* name, const flags_internal::HelpGenFunc help_gen, const char* filename, - const flags_internal::FlagMarshallingOpFn marshalling_op, + const flags_internal::FlagMarshallingOpFn marshalling_op_arg, const flags_internal::InitialValGenFunc initial_value_gen) - : internal(name, flags_internal::HelpText::FromFunctionPointer(help_gen), - filename, &flags_internal::FlagOps, marshalling_op, - initial_value_gen, - /*retired_arg=*/false, /*def_arg=*/nullptr, - /*cur_arg=*/nullptr) {} - - // Not copyable/assignable. - Flag(const Flag&) = delete; - Flag& operator=(const Flag&) = delete; - - absl::string_view Name() const { return internal.Name(); } - std::string Help() const { return internal.Help(); } - std::string Filename() const { return internal.Filename(); } + : flags_internal::CommandLineFlag( + name, flags_internal::HelpText::FromFunctionPointer(help_gen), + filename, &flags_internal::FlagOps, marshalling_op_arg, + initial_value_gen, + /*retired_arg=*/false, /*def_arg=*/nullptr, + /*cur_arg=*/nullptr) {} + + T Get() const { + // Implementation notes: + // + // We are wrapping a union around the value of `T` to serve three purposes: + // + // 1. `U.value` has correct size and alignment for a value of type `T` + // 2. The `U.value` constructor is not invoked since U's constructor does + // not + // do it explicitly. + // 3. The `U.value` destructor is invoked since U's destructor does it + // explicitly. This makes `U` a kind of RAII wrapper around non default + // constructible value of T, which is destructed when we leave the + // scope. We do need to destroy U.value, which is constructed by + // CommandLineFlag::Read even though we left it in a moved-from state + // after std::move. + // + // All of this serves to avoid requiring `T` being default constructible. + union U { + T value; + U() {} + ~U() { value.~T(); } + }; + U u; + + this->Read(&u.value, &flags_internal::FlagOps); + return std::move(u.value); + } - absl::flags_internal::CommandLineFlag internal; + bool AtomicGet(T* v) const { + const int64_t r = this->atomic.load(std::memory_order_acquire); + if (r != flags_internal::CommandLineFlag::kAtomicInit) { + memcpy(v, &r, sizeof(T)); + return true; + } - void SetCallback(const flags_internal::FlagCallback mutation_callback) { - internal.SetCallback(mutation_callback); + return false; } - private: - // TODO(rogeeff): add these validations once UnparseFlag invocation is fixed - // for built-in types and when we cleanup existing code from operating on - // forward declared types. - // auto IsCopyConstructible(const T& v) -> decltype(T(v)); - // auto HasAbslParseFlag(absl::string_view in, T* dst, std::string* err) - // -> decltype(AbslParseFlag(in, dst, err)); - // auto HasAbslUnparseFlag(const T& v) -> decltype(AbslUnparseFlag(v)); + void Set(const T& v) { this->Write(&v, &flags_internal::FlagOps); } }; // This class facilitates Flag object registration and tail expression-based @@ -67,7 +85,7 @@ template class FlagRegistrar { public: explicit FlagRegistrar(Flag* flag) : flag_(flag) { - if (do_register) flags_internal::RegisterCommandLineFlag(&flag_->internal); + if (do_register) flags_internal::RegisterCommandLineFlag(flag_); } FlagRegistrar& OnUpdate(flags_internal::FlagCallback cb) && { diff --git a/absl/flags/internal/registry.cc b/absl/flags/internal/registry.cc index e52cbb68..f37871c9 100644 --- a/absl/flags/internal/registry.cc +++ b/absl/flags/internal/registry.cc @@ -34,13 +34,7 @@ namespace flags_internal { namespace { void DestroyFlag(CommandLineFlag* flag) NO_THREAD_SAFETY_ANALYSIS { - // Values are heap allocated for retired and Abseil Flags. - if (flag->IsRetired() || flag->IsAbseilFlag()) { - if (flag->cur) Delete(flag->op, flag->cur); - if (flag->def) Delete(flag->op, flag->def); - } - - delete flag->locks; + flag->Destroy(); // CommandLineFlag handle object is heap allocated for non Abseil Flags. if (!flag->IsAbseilFlag()) { @@ -48,6 +42,8 @@ void DestroyFlag(CommandLineFlag* flag) NO_THREAD_SAFETY_ANALYSIS { } } +} // namespace + // -------------------------------------------------------------------- // FlagRegistry // A FlagRegistry singleton object holds all flag objects indexed @@ -105,8 +101,6 @@ class FlagPtrMap { }; constexpr size_t FlagPtrMap::kNumBuckets; -} // namespace - class FlagRegistry { public: FlagRegistry() = default; @@ -292,10 +286,10 @@ class FlagSaverImpl { saved.op = flag->op; saved.marshalling_op = flag->marshalling_op; { - absl::MutexLock l(InitFlagIfNecessary(flag)); + absl::MutexLock l(flag->InitFlagIfNecessary()); saved.validator = flag->validator; saved.modified = flag->modified; - saved.on_command_line = flag->IsSpecifiedOnCommandLine(); + saved.on_command_line = flag->on_command_line; saved.current = Clone(saved.op, flag->cur); saved.default_value = Clone(saved.op, flag->def); saved.counter = flag->counter; @@ -318,34 +312,34 @@ class FlagSaverImpl { bool restored = false; { - absl::Mutex* mu = InitFlagIfNecessary(flag); - absl::MutexLock l(mu); + absl::MutexLock l(flag->InitFlagIfNecessary()); flag->validator = src.validator; flag->modified = src.modified; flag->on_command_line = src.on_command_line; if (flag->counter != src.counter || ChangedDirectly(flag, src.default_value, flag->def)) { - flag->counter++; + restored = true; Copy(src.op, src.default_value, flag->def); } if (flag->counter != src.counter || ChangedDirectly(flag, src.current, flag->cur)) { restored = true; - flag->counter++; Copy(src.op, src.current, flag->cur); - UpdateCopy(flag, mu); - - // Revalidate the flag because the validator might store state based - // on the flag's value, which just changed due to the restore. - // Failing validation is ignored because it's assumed that the flag - // was valid previously and there's little that can be done about it - // here, anyway. - Validate(flag, flag->cur); + UpdateCopy(flag); + flag->InvokeCallback(); } } - // Log statements must be done when no flag lock is held. if (restored) { + flag->counter++; + + // Revalidate the flag because the validator might store state based + // on the flag's value, which just changed due to the restore. + // Failing validation is ignored because it's assumed that the flag + // was valid previously and there's little that can be done about it + // here, anyway. + flag->ValidateInputValue(flag->CurrentValue()); + ABSL_INTERNAL_LOG( INFO, absl::StrCat("Restore saved value of ", flag->Name(), ": ", Unparse(src.marshalling_op, src.current))); @@ -412,13 +406,17 @@ void FillCommandLineFlagInfo(CommandLineFlag* flag, result->description = flag->Help(); result->filename = flag->Filename(); - UpdateModifiedBit(flag); + if (!flag->IsAbseilFlag()) { + if (!flag->IsModified() && ChangedDirectly(flag, flag->cur, flag->def)) { + flag->modified = true; + } + } - absl::MutexLock l(InitFlagIfNecessary(flag)); result->current_value = flag->CurrentValue(); result->default_value = flag->DefaultValue(); - result->is_default = !flag->modified; - result->has_validator_fn = (flag->validator != nullptr); + result->is_default = !flag->IsModified(); + result->has_validator_fn = flag->HasValidatorFn(); + absl::MutexLock l(flag->InitFlagIfNecessary()); result->flag_ptr = flag->IsAbseilFlag() ? nullptr : flag->cur; } diff --git a/absl/flags/internal/type_erased.cc b/absl/flags/internal/type_erased.cc index cc103983..2984291c 100644 --- a/absl/flags/internal/type_erased.cc +++ b/absl/flags/internal/type_erased.cc @@ -32,7 +32,6 @@ bool GetCommandLineOption(absl::string_view name, std::string* value) { return false; } - absl::MutexLock l(InitFlagIfNecessary(flag)); *value = flag->CurrentValue(); return true; } @@ -88,22 +87,9 @@ bool SetCommandLineOptionWithMode(absl::string_view name, bool IsValidFlagValue(absl::string_view name, absl::string_view value) { CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); - if (flag == nullptr) { - return false; - } - - if (flag->IsRetired()) { - return true; - } - // No need to lock the flag since we are not mutating it. - void* obj = Clone(flag->op, flag->def); - std::string ignored_error; - const bool result = - flags_internal::Parse(flag->marshalling_op, value, obj, &ignored_error) && - Validate(flag, obj); - Delete(flag->op, obj); - return result; + return flag != nullptr && + (flag->IsRetired() || flag->ValidateInputValue(value)); } // -------------------------------------------------------------------- @@ -111,7 +97,6 @@ bool IsValidFlagValue(absl::string_view name, absl::string_view value) { bool SpecifiedOnCommandLine(absl::string_view name) { CommandLineFlag* flag = flags_internal::FindCommandLineFlag(name); if (flag != nullptr && !flag->IsRetired()) { - absl::MutexLock l(InitFlagIfNecessary(flag)); return flag->IsSpecifiedOnCommandLine(); } return false; diff --git a/absl/flags/internal/usage.cc b/absl/flags/internal/usage.cc index b1ff8b83..aac02db6 100644 --- a/absl/flags/internal/usage.cc +++ b/absl/flags/internal/usage.cc @@ -21,11 +21,11 @@ #include "absl/flags/flag.h" #include "absl/flags/internal/path_util.h" #include "absl/flags/internal/program_name.h" -#include "absl/flags/usage.h" #include "absl/flags/usage_config.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" ABSL_FLAG(bool, help, false, @@ -185,7 +185,7 @@ void FlagHelpHumanReadable(const flags_internal::CommandLineFlag& flag, } printer.Write(absl::StrCat("default: ", dflt_val, ";")); - if (flag.modified) { + if (flag.IsModified()) { std::string curr_val = flag.CurrentValue(); if (flag.IsOfType()) { curr_val = absl::StrCat("\"", curr_val, "\""); @@ -202,10 +202,10 @@ void FlagHelpHumanReadable(const flags_internal::CommandLineFlag& flag, // STRIP_FLAG_HELP 1' then this flag will not be displayed by '--help' // and its variants. void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb, - HelpFormat format = HelpFormat::kHumanReadable) { + HelpFormat format, absl::string_view program_usage_message) { if (format == HelpFormat::kHumanReadable) { out << flags_internal::ShortProgramInvocationName() << ": " - << absl::ProgramUsageMessage() << "\n\n"; + << program_usage_message << "\n\n"; } else { // XML schema is not a part of our public API for now. out << "\n" @@ -214,7 +214,7 @@ void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb, // The program name and usage. << XMLElement("program", flags_internal::ShortProgramInvocationName()) << '\n' - << XMLElement("usage", absl::ProgramUsageMessage()) << '\n'; + << XMLElement("usage", program_usage_message) << '\n'; } // Map of package name to @@ -228,8 +228,6 @@ void FlagsHelpImpl(std::ostream& out, flags_internal::FlagKindFilter filter_cb, matching_flags; flags_internal::ForEachFlag([&](flags_internal::CommandLineFlag* flag) { - absl::MutexLock l(InitFlagIfNecessary(flag)); - std::string flag_filename = flag->Filename(); // Ignore retired flags. @@ -292,44 +290,51 @@ void FlagHelp(std::ostream& out, const flags_internal::CommandLineFlag& flag, // -------------------------------------------------------------------- // Produces the help messages for all flags matching the filter. // If filter is empty produces help messages for all flags. -void FlagsHelp(std::ostream& out, absl::string_view filter, HelpFormat format) { +void FlagsHelp(std::ostream& out, absl::string_view filter, HelpFormat format, + absl::string_view program_usage_message) { flags_internal::FlagKindFilter filter_cb = [&](absl::string_view filename) { return filter.empty() || filename.find(filter) != absl::string_view::npos; }; - flags_internal::FlagsHelpImpl(out, filter_cb, format); + flags_internal::FlagsHelpImpl(out, filter_cb, format, program_usage_message); } // -------------------------------------------------------------------- // Checks all the 'usage' command line flags to see if any have been set. // If so, handles them appropriately. -int HandleUsageFlags(std::ostream& out) { +int HandleUsageFlags(std::ostream& out, + absl::string_view program_usage_message) { if (absl::GetFlag(FLAGS_helpshort)) { flags_internal::FlagsHelpImpl( out, flags_internal::GetUsageConfig().contains_helpshort_flags, - HelpFormat::kHumanReadable); + HelpFormat::kHumanReadable, program_usage_message); return 1; } if (absl::GetFlag(FLAGS_helpfull)) { // show all options - flags_internal::FlagsHelp(out); + flags_internal::FlagsHelp(out, "", HelpFormat::kHumanReadable, + program_usage_message); return 1; } if (!absl::GetFlag(FLAGS_helpon).empty()) { flags_internal::FlagsHelp( - out, absl::StrCat("/", absl::GetFlag(FLAGS_helpon), ".")); + out, absl::StrCat("/", absl::GetFlag(FLAGS_helpon), "."), + HelpFormat::kHumanReadable, program_usage_message); return 1; } if (!absl::GetFlag(FLAGS_helpmatch).empty()) { - flags_internal::FlagsHelp(out, absl::GetFlag(FLAGS_helpmatch)); + flags_internal::FlagsHelp(out, absl::GetFlag(FLAGS_helpmatch), + HelpFormat::kHumanReadable, + program_usage_message); return 1; } if (absl::GetFlag(FLAGS_help)) { flags_internal::FlagsHelpImpl( - out, flags_internal::GetUsageConfig().contains_help_flags); + out, flags_internal::GetUsageConfig().contains_help_flags, + HelpFormat::kHumanReadable, program_usage_message); out << "\nTry --helpfull to get a list of all flags.\n"; @@ -338,7 +343,8 @@ int HandleUsageFlags(std::ostream& out) { if (absl::GetFlag(FLAGS_helppackage)) { flags_internal::FlagsHelpImpl( - out, flags_internal::GetUsageConfig().contains_helppackage_flags); + out, flags_internal::GetUsageConfig().contains_helppackage_flags, + HelpFormat::kHumanReadable, program_usage_message); out << "\nTry --helpfull to get a list of all flags.\n"; diff --git a/absl/flags/internal/usage.h b/absl/flags/internal/usage.h index 33f3f969..76075b08 100644 --- a/absl/flags/internal/usage.h +++ b/absl/flags/internal/usage.h @@ -47,8 +47,8 @@ void FlagHelp(std::ostream& out, const flags_internal::CommandLineFlag& flag, // .../path/to/file. // for any extension 'ext'. If the filter is empty this function produces help // messages for all flags. -void FlagsHelp(std::ostream& out, absl::string_view filter = {}, - HelpFormat format = HelpFormat::kHumanReadable); +void FlagsHelp(std::ostream& out, absl::string_view filter, + HelpFormat format, absl::string_view program_usage_message); // -------------------------------------------------------------------- @@ -60,7 +60,8 @@ void FlagsHelp(std::ostream& out, absl::string_view filter = {}, // -1 - if no usage flags were set on a commmand line. // Non negative return values are expected to be used as an exit code for a // binary. -int HandleUsageFlags(std::ostream& out); +int HandleUsageFlags(std::ostream& out, + absl::string_view program_usage_message); } // namespace flags_internal } // namespace absl diff --git a/absl/flags/internal/usage_test.cc b/absl/flags/internal/usage_test.cc index fa121fc9..5e5f7a84 100644 --- a/absl/flags/internal/usage_test.cc +++ b/absl/flags/internal/usage_test.cc @@ -36,6 +36,8 @@ ABSL_FLAG(double, usage_reporting_test_flag_03, 1.03, ABSL_FLAG(int64_t, usage_reporting_test_flag_04, 1000000000000004L, "usage_reporting_test_flag_04 help message"); +static const char kTestUsageMessage[] = "Custom usage message"; + struct UDT { UDT() = default; UDT(const UDT&) = default; @@ -83,7 +85,7 @@ class UsageReportingTest : public testing::Test { using UsageReportingDeathTest = UsageReportingTest; TEST_F(UsageReportingDeathTest, TestSetProgramUsageMessage) { - EXPECT_EQ(absl::ProgramUsageMessage(), "Custom usage message"); + EXPECT_EQ(absl::ProgramUsageMessage(), kTestUsageMessage); #ifndef _WIN32 // TODO(rogeeff): figure out why this does not work on Windows. @@ -175,22 +177,22 @@ TEST_F(UsageReportingTest, TestFlagsHelpHRF) { std::stringstream test_buf_01; flags::FlagsHelp(test_buf_01, "usage_test.cc", - flags::HelpFormat::kHumanReadable); + flags::HelpFormat::kHumanReadable, kTestUsageMessage); EXPECT_EQ(test_buf_01.str(), usage_test_flags_out); std::stringstream test_buf_02; flags::FlagsHelp(test_buf_02, "flags/internal/usage_test.cc", - flags::HelpFormat::kHumanReadable); + flags::HelpFormat::kHumanReadable, kTestUsageMessage); EXPECT_EQ(test_buf_02.str(), usage_test_flags_out); std::stringstream test_buf_03; - flags::FlagsHelp(test_buf_03, "usage_test", - flags::HelpFormat::kHumanReadable); + flags::FlagsHelp(test_buf_03, "usage_test", flags::HelpFormat::kHumanReadable, + kTestUsageMessage); EXPECT_EQ(test_buf_03.str(), usage_test_flags_out); std::stringstream test_buf_04; flags::FlagsHelp(test_buf_04, "flags/invalid_file_name.cc", - flags::HelpFormat::kHumanReadable); + flags::HelpFormat::kHumanReadable, kTestUsageMessage); EXPECT_EQ(test_buf_04.str(), R"(usage_test: Custom usage message @@ -198,7 +200,8 @@ TEST_F(UsageReportingTest, TestFlagsHelpHRF) { )"); std::stringstream test_buf_05; - flags::FlagsHelp(test_buf_05, "", flags::HelpFormat::kHumanReadable); + flags::FlagsHelp(test_buf_05, "", flags::HelpFormat::kHumanReadable, + kTestUsageMessage); std::string test_out = test_buf_05.str(); absl::string_view test_out_str(test_out); EXPECT_TRUE( @@ -217,7 +220,7 @@ TEST_F(UsageReportingTest, TestFlagsHelpHRF) { TEST_F(UsageReportingTest, TestNoUsageFlags) { std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf), -1); + EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), -1); } // -------------------------------------------------------------------- @@ -226,7 +229,7 @@ TEST_F(UsageReportingTest, TestUsageFlag_helpshort) { absl::SetFlag(&FLAGS_helpshort, true); std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf), 1); + EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); EXPECT_EQ(test_buf.str(), R"(usage_test: Custom usage message @@ -250,7 +253,7 @@ TEST_F(UsageReportingTest, TestUsageFlag_help) { absl::SetFlag(&FLAGS_help, true); std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf), 1); + EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); EXPECT_EQ(test_buf.str(), R"(usage_test: Custom usage message @@ -276,7 +279,7 @@ TEST_F(UsageReportingTest, TestUsageFlag_helppackage) { absl::SetFlag(&FLAGS_helppackage, true); std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf), 1); + EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 1); EXPECT_EQ(test_buf.str(), R"(usage_test: Custom usage message @@ -302,10 +305,9 @@ TEST_F(UsageReportingTest, TestUsageFlag_version) { absl::SetFlag(&FLAGS_version, true); std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf), 0); + EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0); #ifndef NDEBUG - EXPECT_EQ(test_buf.str(), - "usage_test\nDebug build (NDEBUG not #defined)\n"); + EXPECT_EQ(test_buf.str(), "usage_test\nDebug build (NDEBUG not #defined)\n"); #else EXPECT_EQ(test_buf.str(), "usage_test\n"); #endif @@ -317,7 +319,7 @@ TEST_F(UsageReportingTest, TestUsageFlag_only_check_args) { absl::SetFlag(&FLAGS_only_check_args, true); std::stringstream test_buf; - EXPECT_EQ(flags::HandleUsageFlags(test_buf), 0); + EXPECT_EQ(flags::HandleUsageFlags(test_buf, kTestUsageMessage), 0); EXPECT_EQ(test_buf.str(), ""); } @@ -327,7 +329,7 @@ TEST_F(UsageReportingTest, TestUsageFlag_helpon) { absl::SetFlag(&FLAGS_helpon, "bla-bla"); std::stringstream test_buf_01; - EXPECT_EQ(flags::HandleUsageFlags(test_buf_01), 1); + EXPECT_EQ(flags::HandleUsageFlags(test_buf_01, kTestUsageMessage), 1); EXPECT_EQ(test_buf_01.str(), R"(usage_test: Custom usage message @@ -337,7 +339,7 @@ TEST_F(UsageReportingTest, TestUsageFlag_helpon) { absl::SetFlag(&FLAGS_helpon, "usage_test"); std::stringstream test_buf_02; - EXPECT_EQ(flags::HandleUsageFlags(test_buf_02), 1); + EXPECT_EQ(flags::HandleUsageFlags(test_buf_02, kTestUsageMessage), 1); EXPECT_EQ(test_buf_02.str(), R"(usage_test: Custom usage message @@ -362,7 +364,7 @@ TEST_F(UsageReportingTest, TestUsageFlag_helpon) { int main(int argc, char* argv[]) { absl::GetFlag(FLAGS_undefok); // Force linking of parse.cc flags::SetProgramInvocationName("usage_test"); - absl::SetProgramUsageMessage("Custom usage message"); + absl::SetProgramUsageMessage(kTestUsageMessage); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc index 3caaa1c2..e9dd4204 100644 --- a/absl/flags/parse.cc +++ b/absl/flags/parse.cc @@ -16,6 +16,7 @@ #include "absl/flags/parse.h" #include + #include #include #include @@ -28,6 +29,7 @@ #include "absl/flags/internal/program_name.h" #include "absl/flags/internal/registry.h" #include "absl/flags/internal/usage.h" +#include "absl/flags/usage.h" #include "absl/flags/usage_config.h" #include "absl/strings/str_cat.h" #include "absl/strings/strip.h" @@ -280,22 +282,7 @@ void CheckDefaultValuesParsingRoundtrip() { IGNORE_TYPE(std::vector) #undef IGNORE_TYPE - absl::MutexLock lock(InitFlagIfNecessary(flag)); - - std::string v = flag->DefaultValue(); - void* dst = Clone(flag->op, flag->def); - std::string error; - if (!flags_internal::Parse(flag->marshalling_op, v, dst, &error)) { - ABSL_INTERNAL_LOG( - FATAL, - absl::StrCat("Flag ", flag->Name(), " (from ", flag->Filename(), - "): std::string form of default value '", v, - "' could not be parsed; error=", error)); - } - - // We do not compare dst to def since parsing/unparsing may make - // small changes, e.g., precision loss for floating point types. - Delete(flag->op, dst); + flag->CheckDefaultValueParsingRoundtrip(); }); #endif } @@ -717,12 +704,14 @@ std::vector ParseCommandLineImpl(int argc, char* argv[], #endif if (!success) { - flags_internal::HandleUsageFlags(std::cout); + flags_internal::HandleUsageFlags(std::cout, + ProgramUsageMessage()); std::exit(1); } if (usage_flag_act == UsageFlagsAction::kHandleUsage) { - int exit_code = flags_internal::HandleUsageFlags(std::cout); + int exit_code = flags_internal::HandleUsageFlags( + std::cout, ProgramUsageMessage()); if (exit_code != -1) { std::exit(exit_code); diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index bab560bd..9a667ba7 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -288,7 +288,6 @@ TEST(HashValueTest, Strings) { // Also check that nested types maintain the same hash. const WrapInTuple t{}; EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( - // t(std::string()), t(absl::string_view()), t(std::string("")), t(absl::string_view("")), t(std::string(small)), t(absl::string_view(small)), diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 18665173..4ff4a126 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -640,7 +640,8 @@ class CityHashState : public HashStateBase { #endif // ABSL_HAVE_INTRINSIC_INT128 static constexpr uint64_t kMul = - sizeof(size_t) == 4 ? uint64_t{0xcc9e2d51} : uint64_t{0x9ddfea08eb382d69}; + sizeof(size_t) == 4 ? uint64_t{0xcc9e2d51} + : uint64_t{0x9ddfea08eb382d69}; template using IntegralFastPath = diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 2f5b8ad7..10be8eca 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -19,8 +19,8 @@ // // This header file defines 128-bit integer types. // -// Currently, this file defines `uint128`, an unsigned 128-bit integer; a signed -// 128-bit integer is forthcoming. +// Currently, this file defines `uint128`, an unsigned 128-bit integer; +// a signed 128-bit integer is forthcoming. #ifndef ABSL_NUMERIC_INT128_H_ #define ABSL_NUMERIC_INT128_H_ diff --git a/absl/random/internal/fast_uniform_bits.h b/absl/random/internal/fast_uniform_bits.h index 184a2708..e8df92f3 100644 --- a/absl/random/internal/fast_uniform_bits.h +++ b/absl/random/internal/fast_uniform_bits.h @@ -22,11 +22,18 @@ namespace absl { 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 +template +constexpr bool IsPowerOfTwoOrZero(UIntType n) { + return (n == 0) || ((n & (n - 1)) == 0); +} + // Computes the length of the range of values producible by the URBG, or returns // zero if that would encompass the entire range of representable values in // URBG::result_type. template -constexpr typename URBG::result_type constexpr_range() { +constexpr typename URBG::result_type RangeSize() { using result_type = typename URBG::result_type; return ((URBG::max)() == (std::numeric_limits::max)() && (URBG::min)() == std::numeric_limits::lowest()) @@ -34,6 +41,42 @@ constexpr typename URBG::result_type constexpr_range() { : (URBG::max)() - (URBG::min)() + result_type{1}; } +template +constexpr UIntType LargestPowerOfTwoLessThanOrEqualTo(UIntType n) { + return n < 2 ? n : 2 * LargestPowerOfTwoLessThanOrEqualTo(n / 2); +} + +// Given a URBG generating values in the closed interval [Lo, Hi], returns the +// largest power of two less than or equal to `Hi - Lo + 1`. +template +constexpr typename URBG::result_type PowerOfTwoSubRangeSize() { + return LargestPowerOfTwoLessThanOrEqualTo(RangeSize()); +} + +// Computes the floor of the log. (i.e., std::floor(std::log2(N)); +template +constexpr UIntType IntegerLog2(UIntType n) { + return (n <= 1) ? 0 : 1 + IntegerLog2(n / 2); +} + +// Returns the number of bits of randomness returned through +// `PowerOfTwoVariate(urbg)`. +template +constexpr size_t NumBits() { + return RangeSize() == 0 + ? std::numeric_limits::digits + : IntegerLog2(PowerOfTwoSubRangeSize()); +} + +// Given a shift value `n`, constructs a mask with exactly the low `n` bits set. +// If `n == 0`, all bits are set. +template +constexpr UIntType MaskFromShift(UIntType n) { + return ((n % std::numeric_limits::digits) == 0) + ? ~UIntType{0} + : (UIntType{1} << n) - UIntType{1}; +} + // FastUniformBits implements a fast path to acquire uniform independent bits // from a type which conforms to the [rand.req.urbg] concept. // Parameterized by: @@ -45,14 +88,6 @@ constexpr typename URBG::result_type constexpr_range() { // generator that will outlive the std::independent_bits_engine instance. template class FastUniformBits { - static_assert(std::is_unsigned::value, - "Class-template FastUniformBits<> must be parameterized using " - "an unsigned type."); - - // `kWidth` is the width, in binary digits, of the output. By default it is - // the number of binary digits in the `result_type`. - static constexpr size_t kWidth = std::numeric_limits::digits; - public: using result_type = UIntType; @@ -65,14 +100,47 @@ class FastUniformBits { result_type operator()(URBG& g); // NOLINT(runtime/references) private: - // Variate() generates a single random variate, always returning a value - // in the closed interval [0 ... FastUniformBitsURBGConstants::kRangeMask] - // (kRangeMask+1 is a power of 2). + static_assert(std::is_unsigned::value, + "Class-template FastUniformBits<> must be parameterized using " + "an unsigned type."); + + // PowerOfTwoVariate() generates a single random variate, always returning a + // value in the half-open interval `[0, PowerOfTwoSubRangeSize())`. If + // the URBG already generates values in a power-of-two range, the generator + // itself is used. Otherwise, we use rejection sampling on the largest + // possible power-of-two-sized subrange. + struct PowerOfTwoTag {}; + struct RejectionSamplingTag {}; template - typename URBG::result_type Variate(URBG& g); // NOLINT(runtime/references) + static typename URBG::result_type PowerOfTwoVariate( + URBG& g) { // NOLINT(runtime/references) + using tag = + typename std::conditional()), + PowerOfTwoTag, RejectionSamplingTag>::type; + return PowerOfTwoVariate(g, tag{}); + } + + template + static typename URBG::result_type PowerOfTwoVariate( + URBG& g, // NOLINT(runtime/references) + PowerOfTwoTag) { + return g() - (URBG::min)(); + } - // generate() generates a random value, dispatched on whether - // the underlying URNG must loop over multiple calls or not. + template + static typename URBG::result_type PowerOfTwoVariate( + URBG& g, // NOLINT(runtime/references) + RejectionSamplingTag) { + // Use rejection sampling to ensure uniformity across the range. + typename URBG::result_type u; + do { + u = g() - (URBG::min)(); + } while (u >= PowerOfTwoSubRangeSize()); + return u; + } + + // Generate() generates a random value, dispatched on whether + // the underlying URBG must loop over multiple calls or not. template result_type Generate(URBG& g, // NOLINT(runtime/references) std::true_type /* avoid_looping */); @@ -82,196 +150,107 @@ class FastUniformBits { std::false_type /* avoid_looping */); }; -// FastUniformBitsURBGConstants computes the URBG-derived constants used -// by FastUniformBits::Generate and FastUniformBits::Variate. -// Parameterized by the FastUniformBits parameter: -// `URBG`: The underlying UniformRandomNumberGenerator. -// -// The values here indicate the URBG range as well as providing an indicator -// whether the URBG output is a power of 2, and kRangeMask, which allows masking -// the generated output to kRangeBits. +template template -class FastUniformBitsURBGConstants { - // Computes the floor of the log. (i.e., std::floor(std::log2(N)); - static constexpr size_t constexpr_log2(size_t n) { - return (n <= 1) ? 0 : 1 + constexpr_log2(n / 2); - } - - // Computes a mask of n bits for the URBG::result_type. - static constexpr typename URBG::result_type constexpr_mask(size_t n) { - return (typename URBG::result_type(1) << n) - 1; - } - - public: - using result_type = typename URBG::result_type; - - // The range of the URNG, max - min + 1, or zero if that result would cause - // overflow. - static constexpr result_type kRange = constexpr_range(); - - static constexpr bool kPowerOfTwo = - (kRange == 0) || ((kRange & (kRange - 1)) == 0); - - // kRangeBits describes the number number of bits suitable to mask off of URNG - // variate, which is: - // kRangeBits = floor(log2(kRange)) - static constexpr size_t kRangeBits = - kRange == 0 ? std::numeric_limits::digits - : constexpr_log2(kRange); - - // kRangeMask is the mask used when sampling variates from the URNG when the - // width of the URNG range is not a power of 2. +typename FastUniformBits::result_type +FastUniformBits::operator()(URBG& g) { // NOLINT(runtime/references) + // kRangeMask is the mask used when sampling variates from the URBG when the + // width of the URBG range is not a power of 2. // Y = (2 ^ kRange) - 1 - static constexpr result_type kRangeMask = - kRange == 0 ? (std::numeric_limits::max)() - : constexpr_mask(kRangeBits); - - static_assert((URBG::max)() != (URBG::min)(), - "Class-template FastUniformBitsURBGConstants<> " + static_assert((URBG::max)() > (URBG::min)(), "URBG::max and URBG::min may not be equal."); - - static_assert(std::is_unsigned::value, - "Class-template FastUniformBitsURBGConstants<> " - "URBG::result_type must be unsigned."); - - static_assert(kRangeMask > 0, - "Class-template FastUniformBitsURBGConstants<> " - "URBG does not generate sufficient random bits."); - - static_assert(kRange == 0 || - kRangeBits < std::numeric_limits::digits, - "Class-template FastUniformBitsURBGConstants<> " - "URBG range computation error."); -}; - -// FastUniformBitsLoopingConstants computes the looping constants used -// by FastUniformBits::Generate. These constants indicate how multiple -// URBG::result_type values are combined into an output_value. -// Parameterized by the FastUniformBits parameters: -// `UIntType`: output type. -// `URNG`: The underlying UniformRandomNumberGenerator. -// -// The looping constants describe the sets of loop counters and mask values -// which control how individual variates are combined the final output. The -// algorithm ensures that the number of bits used by any individual call differs -// by at-most one bit from any other call. This is simplified into constants -// which describe two loops, with the second loop parameters providing one extra -// bit per variate. -// -// See [rand.adapt.ibits] for more details on the use of these constants. -template -class FastUniformBitsLoopingConstants { - private: - static constexpr size_t kWidth = std::numeric_limits::digits; using urbg_result_type = typename URBG::result_type; - using uint_result_type = UIntType; - - public: - using result_type = - typename std::conditional<(sizeof(urbg_result_type) <= - sizeof(uint_result_type)), - uint_result_type, urbg_result_type>::type; - - private: - // Estimate N as ceil(width / urng width), and W0 as (width / N). - static constexpr size_t kRangeBits = - FastUniformBitsURBGConstants::kRangeBits; - - // The range of the URNG, max - min + 1, or zero if that result would cause - // overflow. - static constexpr result_type kRange = constexpr_range(); - static constexpr size_t kEstimateN = - kWidth / kRangeBits + (kWidth % kRangeBits != 0); - static constexpr size_t kEstimateW0 = kWidth / kEstimateN; - static constexpr result_type kEstimateY0 = (kRange >> kEstimateW0) - << kEstimateW0; - - public: - // Parameters for the two loops: - // kN0, kN1 are the number of underlying calls required for each loop. - // KW0, kW1 are shift widths for each loop. - // - static constexpr size_t kN1 = (kRange - kEstimateY0) > - (kEstimateY0 / kEstimateN) - ? kEstimateN + 1 - : kEstimateN; - static constexpr size_t kN0 = kN1 - (kWidth % kN1); - static constexpr size_t kW0 = kWidth / kN1; - static constexpr size_t kW1 = kW0 + 1; - - static constexpr result_type kM0 = (result_type(1) << kW0) - 1; - static constexpr result_type kM1 = (result_type(1) << kW1) - 1; - - static_assert( - kW0 <= kRangeBits, - "Class-template FastUniformBitsLoopingConstants::kW0 too large."); - - static_assert( - kW0 > 0, - "Class-template FastUniformBitsLoopingConstants::kW0 too small."); -}; - -template -template -typename FastUniformBits::result_type -FastUniformBits::operator()( - URBG& g) { // NOLINT(runtime/references) - using constants = FastUniformBitsURBGConstants; - return Generate( - g, std::integral_constant= (max)()>{}); -} - -template -template -typename URBG::result_type FastUniformBits::Variate( - URBG& g) { // NOLINT(runtime/references) - using constants = FastUniformBitsURBGConstants; - if (constants::kPowerOfTwo) { - return g() - (URBG::min)(); - } - - // Use rejection sampling to ensure uniformity across the range. - typename URBG::result_type u; - do { - u = g() - (URBG::min)(); - } while (u > constants::kRangeMask); - return u; + constexpr urbg_result_type kRangeMask = + RangeSize() == 0 + ? (std::numeric_limits::max)() + : static_cast(PowerOfTwoSubRangeSize() - 1); + return Generate(g, std::integral_constant= (max)())>{}); } template template typename FastUniformBits::result_type -FastUniformBits::Generate( - URBG& g, // NOLINT(runtime/references) - std::true_type /* avoid_looping */) { +FastUniformBits::Generate(URBG& g, // NOLINT(runtime/references) + std::true_type /* avoid_looping */) { // The width of the result_type is less than than the width of the random bits - // provided by URNG. Thus, generate a single value and then simply mask off + // provided by URBG. Thus, generate a single value and then simply mask off // the required bits. - return Variate(g) & (max)(); + + return PowerOfTwoVariate(g) & (max)(); } template template typename FastUniformBits::result_type -FastUniformBits::Generate( - URBG& g, // NOLINT(runtime/references) - std::false_type /* avoid_looping */) { - // The width of the result_type is wider than the number of random bits - // provided by URNG. Thus we merge several variates of URNG into the result - // using a shift and mask. The constants type generates the parameters used - // ensure that the bits are distributed across all the invocations of the - // underlying URNG. - using constants = FastUniformBitsLoopingConstants; +FastUniformBits::Generate(URBG& g, // NOLINT(runtime/references) + std::false_type /* avoid_looping */) { + // See [rand.adapt.ibits] for more details on the constants calculated below. + // + // It is preferable to use roughly the same number of bits from each generator + // call, however this is only possible when the number of bits provided by the + // URBG is a divisor of the number of bits in `result_type`. In all other + // cases, the number of bits used cannot always be the same, but it can be + // guaranteed to be off by at most 1. Thus we run two loops, one with a + // smaller bit-width size (`kSmallWidth`) and one with a larger width size + // (satisfying `kLargeWidth == kSmallWidth + 1`). The loops are run + // `kSmallIters` and `kLargeIters` times respectively such + // that + // + // `kTotalWidth == kSmallIters * kSmallWidth + // + kLargeIters * kLargeWidth` + // + // where `kTotalWidth` is the total number of bits in `result_type`. + // + constexpr size_t kTotalWidth = std::numeric_limits::digits; + constexpr size_t kUrbgWidth = NumBits(); + constexpr size_t kTotalIters = + kTotalWidth / kUrbgWidth + (kTotalWidth % kUrbgWidth != 0); + constexpr size_t kSmallWidth = kTotalWidth / kTotalIters; + constexpr size_t kLargeWidth = kSmallWidth + 1; + // + // Because `kLargeWidth == kSmallWidth + 1`, it follows that + // + // `kTotalWidth == kTotalIters * kSmallWidth + kLargeIters` + // + // and therefore + // + // `kLargeIters == kTotalWidth % kSmallWidth` + // + // Intuitively, each iteration with the large width accounts for one unit + // of the remainder when `kTotalWidth` is divided by `kSmallWidth`. As + // mentioned above, if the URBG width is a divisor of `kTotalWidth`, then + // there would be no need for any large iterations (i.e., one loop would + // suffice), and indeed, in this case, `kLargeIters` would be zero. + constexpr size_t kLargeIters = kTotalWidth % kSmallWidth; + constexpr size_t kSmallIters = + (kTotalWidth - (kLargeWidth * kLargeIters)) / kSmallWidth; + + static_assert( + kTotalWidth == kSmallIters * kSmallWidth + kLargeIters * kLargeWidth, + "Error in looping constant calculations."); result_type s = 0; - for (size_t n = 0; n < constants::kN0; ++n) { - auto u = Variate(g); - s = (s << constants::kW0) + (u & constants::kM0); + + constexpr size_t kSmallShift = kSmallWidth % kTotalWidth; + constexpr result_type kSmallMask = MaskFromShift(result_type{kSmallShift}); + for (size_t n = 0; n < kSmallIters; ++n) { + s = (s << kSmallShift) + + (static_cast(PowerOfTwoVariate(g)) & kSmallMask); } - for (size_t n = constants::kN0; n < constants::kN1; ++n) { - auto u = Variate(g); - s = (s << constants::kW1) + (u & constants::kM1); + + constexpr size_t kLargeShift = kLargeWidth % kTotalWidth; + constexpr result_type kLargeMask = MaskFromShift(result_type{kLargeShift}); + for (size_t n = 0; n < kLargeIters; ++n) { + s = (s << kLargeShift) + + (static_cast(PowerOfTwoVariate(g)) & kLargeMask); } + + static_assert( + kLargeShift == kSmallShift + 1 || + (kLargeShift == 0 && + kSmallShift == std::numeric_limits::digits - 1), + "Error in looping constant calculations"); + return s; } diff --git a/absl/random/internal/fast_uniform_bits_test.cc b/absl/random/internal/fast_uniform_bits_test.cc index 18377944..9f2e8268 100644 --- a/absl/random/internal/fast_uniform_bits_test.cc +++ b/absl/random/internal/fast_uniform_bits_test.cc @@ -18,6 +18,8 @@ #include "gtest/gtest.h" +namespace absl { +namespace random_internal { namespace { template @@ -29,7 +31,7 @@ TYPED_TEST_SUITE(FastUniformBitsTypedTest, IntTypes); TYPED_TEST(FastUniformBitsTypedTest, BasicTest) { using Limits = std::numeric_limits; - using FastBits = absl::random_internal::FastUniformBits; + using FastBits = FastUniformBits; EXPECT_EQ(0, FastBits::min()); EXPECT_EQ(Limits::max(), FastBits::max()); @@ -45,91 +47,226 @@ TYPED_TEST(FastUniformBitsTypedTest, BasicTest) { } } -class UrngOddbits { - public: - using result_type = uint8_t; - static constexpr result_type min() { return 1; } - static constexpr result_type max() { return 0xfe; } - result_type operator()() { return 2; } -}; +template +struct FakeUrbg { + using result_type = UIntType; -class Urng4bits { - public: - using result_type = uint8_t; - static constexpr result_type min() { return 1; } - static constexpr result_type max() { return 0xf + 1; } - result_type operator()() { return 2; } + static constexpr result_type(max)() { return Hi; } + static constexpr result_type(min)() { return Lo; } + result_type operator()() { return Val; } }; -class Urng32bits { - public: - using result_type = uint32_t; - static constexpr result_type min() { return 0; } - static constexpr result_type max() { return 0xffffffff; } - result_type operator()() { return 1; } -}; +using UrngOddbits = FakeUrbg; +using Urng4bits = FakeUrbg; +using Urng31bits = FakeUrbg; +using Urng32bits = FakeUrbg; -// Compile-time test to validate the helper classes used by FastUniformBits -TEST(FastUniformBitsTest, FastUniformBitsDetails) { - using absl::random_internal::FastUniformBitsLoopingConstants; - using absl::random_internal::FastUniformBitsURBGConstants; +TEST(FastUniformBitsTest, IsPowerOfTwoOrZero) { + EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{0})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{1})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{2})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint8_t{3})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint8_t{16})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint8_t{17})); + EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits::max)())); - // 4-bit URBG - { - using constants = FastUniformBitsURBGConstants; - static_assert(constants::kPowerOfTwo == true, - "constants::kPowerOfTwo == false"); - static_assert(constants::kRange == 16, "constants::kRange == false"); - static_assert(constants::kRangeBits == 4, "constants::kRangeBits == false"); - static_assert(constants::kRangeMask == 0x0f, - "constants::kRangeMask == false"); - } + EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{0})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{1})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{2})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint16_t{3})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint16_t{16})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint16_t{17})); + EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits::max)())); - // ~7-bit URBG - { - using constants = FastUniformBitsURBGConstants; - static_assert(constants::kPowerOfTwo == false, - "constants::kPowerOfTwo == false"); - static_assert(constants::kRange == 0xfe, "constants::kRange == 0xfe"); - static_assert(constants::kRangeBits == 7, "constants::kRangeBits == 7"); - static_assert(constants::kRangeMask == 0x7f, - "constants::kRangeMask == 0x7f"); - } + EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{0})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{1})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{2})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint32_t{3})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint32_t{32})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint32_t{17})); + EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits::max)())); + + EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{0})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{1})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{2})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint64_t{3})); + EXPECT_TRUE(IsPowerOfTwoOrZero(uint64_t{64})); + EXPECT_FALSE(IsPowerOfTwoOrZero(uint64_t{17})); + EXPECT_FALSE(IsPowerOfTwoOrZero((std::numeric_limits::max)())); +} + +TEST(FastUniformBitsTest, IntegerLog2) { + EXPECT_EQ(IntegerLog2(uint16_t{0}), 0); + EXPECT_EQ(IntegerLog2(uint16_t{1}), 0); + EXPECT_EQ(IntegerLog2(uint16_t{2}), 1); + EXPECT_EQ(IntegerLog2(uint16_t{3}), 1); + EXPECT_EQ(IntegerLog2(uint16_t{4}), 2); + EXPECT_EQ(IntegerLog2(uint16_t{5}), 2); + EXPECT_EQ(IntegerLog2(std::numeric_limits::max()), 63); +} + +TEST(FastUniformBitsTest, RangeSize) { + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 1); + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 5); + EXPECT_EQ((RangeSize>()), 9); + EXPECT_EQ( + (RangeSize::max()>>()), + 0); + + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 1); + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 5); + EXPECT_EQ((RangeSize>()), 18); + EXPECT_EQ((RangeSize< + FakeUrbg::max()>>()), + 0); + + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 1); + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 5); + EXPECT_EQ((RangeSize>()), 18); + EXPECT_EQ((RangeSize>()), 0); + EXPECT_EQ((RangeSize>()), 0xffffffff); + EXPECT_EQ((RangeSize>()), 0xfffffffe); + EXPECT_EQ((RangeSize>()), 0xfffffffd); + EXPECT_EQ((RangeSize< + FakeUrbg::max()>>()), + 0); + + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 1); + EXPECT_EQ((RangeSize>()), 4); + EXPECT_EQ((RangeSize>()), 5); + EXPECT_EQ((RangeSize>()), 18); + EXPECT_EQ((RangeSize>()), 0x100000000ull); + EXPECT_EQ((RangeSize>()), 0xffffffffull); + EXPECT_EQ((RangeSize>()), 0xfffffffeull); + EXPECT_EQ((RangeSize>()), 0xfffffffdull); + EXPECT_EQ((RangeSize>()), 0ull); + EXPECT_EQ((RangeSize>()), + 0xffffffffffffffffull); + EXPECT_EQ((RangeSize>()), + 0xfffffffffffffffeull); + EXPECT_EQ((RangeSize>()), + 0xfffffffffffffffdull); + EXPECT_EQ((RangeSize< + FakeUrbg::max()>>()), + 0); +} + +TEST(FastUniformBitsTest, PowerOfTwoSubRangeSize) { + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 1); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 8); + EXPECT_EQ((PowerOfTwoSubRangeSize< + FakeUrbg::max()>>()), + 0); + + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 1); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 16); + EXPECT_EQ((PowerOfTwoSubRangeSize< + FakeUrbg::max()>>()), + 0); + + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 1); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 16); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 0); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), + 0x80000000); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), + 0x80000000); + EXPECT_EQ((PowerOfTwoSubRangeSize< + FakeUrbg::max()>>()), + 0); + + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 1); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 4); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), 16); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), + 0x100000000ull); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), + 0x80000000ull); + EXPECT_EQ((PowerOfTwoSubRangeSize>()), + 0x80000000ull); + EXPECT_EQ( + (PowerOfTwoSubRangeSize>()), + 0); + EXPECT_EQ( + (PowerOfTwoSubRangeSize>()), + 0x8000000000000000ull); + EXPECT_EQ( + (PowerOfTwoSubRangeSize>()), + 0x8000000000000000ull); + EXPECT_EQ((PowerOfTwoSubRangeSize< + FakeUrbg::max()>>()), + 0); } TEST(FastUniformBitsTest, Urng4_VariousOutputs) { // Tests that how values are composed; the single-bit deltas should be spread // across each invocation. Urng4bits urng4; + Urng31bits urng31; Urng32bits urng32; // 8-bit types { - absl::random_internal::FastUniformBits fast8; + FastUniformBits fast8; EXPECT_EQ(0x11, fast8(urng4)); + EXPECT_EQ(0x2, fast8(urng31)); EXPECT_EQ(0x1, fast8(urng32)); } // 16-bit types { - absl::random_internal::FastUniformBits fast16; + FastUniformBits fast16; EXPECT_EQ(0x1111, fast16(urng4)); - EXPECT_EQ(0x1, fast16(urng32)); + EXPECT_EQ(0xf02, fast16(urng31)); + EXPECT_EQ(0xf01, fast16(urng32)); } // 32-bit types { - absl::random_internal::FastUniformBits fast32; + FastUniformBits fast32; EXPECT_EQ(0x11111111, fast32(urng4)); - EXPECT_EQ(0x1, fast32(urng32)); + EXPECT_EQ(0x0f020f02, fast32(urng31)); + EXPECT_EQ(0x74010f01, fast32(urng32)); } // 64-bit types { - absl::random_internal::FastUniformBits fast64; + FastUniformBits fast64; EXPECT_EQ(0x1111111111111111, fast64(urng4)); - EXPECT_EQ(0x0000000100000001, fast64(urng32)); + EXPECT_EQ(0x387811c3c0870f02, fast64(urng31)); + EXPECT_EQ(0x74010f0174010f01, fast64(urng32)); } } +TEST(FastUniformBitsTest, URBG32bitRegression) { + // Validate with deterministic 32-bit std::minstd_rand + // to ensure that operator() performs as expected. + std::minstd_rand gen(1); + FastUniformBits fast64; + + EXPECT_EQ(0x05e47095f847c122ull, fast64(gen)); + EXPECT_EQ(0x8f82c1ba30b64d22ull, fast64(gen)); + EXPECT_EQ(0x3b971a3558155039ull, fast64(gen)); +} + } // namespace +} // namespace random_internal +} // namespace absl diff --git a/absl/strings/str_join.h b/absl/strings/str_join.h index 7345b962..4772f5d1 100644 --- a/absl/strings/str_join.h +++ b/absl/strings/str_join.h @@ -254,7 +254,7 @@ std::string StrJoin(const Range& range, absl::string_view separator, template std::string StrJoin(std::initializer_list il, absl::string_view separator, - Formatter&& fmt) { + Formatter&& fmt) { return strings_internal::JoinRange(il, separator, fmt); } @@ -275,7 +275,8 @@ std::string StrJoin(const Range& range, absl::string_view separator) { } template -std::string StrJoin(std::initializer_list il, absl::string_view separator) { +std::string StrJoin(std::initializer_list il, + absl::string_view separator) { return strings_internal::JoinRange(il, separator); } diff --git a/absl/synchronization/internal/create_thread_identity.cc b/absl/synchronization/internal/create_thread_identity.cc index 6e93605d..ce3676a8 100644 --- a/absl/synchronization/internal/create_thread_identity.cc +++ b/absl/synchronization/internal/create_thread_identity.cc @@ -31,7 +31,8 @@ namespace synchronization_internal { // ThreadIdentity storage is persistent, we maintain a free-list of previously // released ThreadIdentity objects. -static base_internal::SpinLock freelist_lock(base_internal::kLinkerInitialized); +static base_internal::SpinLock freelist_lock( + base_internal::kLinkerInitialized); static base_internal::ThreadIdentity* thread_identity_freelist; // A per-thread destructor for reclaiming associated ThreadIdentity objects. diff --git a/absl/time/time.h b/absl/time/time.h index 05347805..e236870b 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -179,6 +179,7 @@ class Duration { Duration& operator%=(Duration rhs); // Overloads that forward to either the int64_t or double overloads above. + // Integer operands must be representable as int64_t. template Duration& operator*=(T r) { int64_t x = r; @@ -221,6 +222,7 @@ inline Duration operator+(Duration lhs, Duration rhs) { return lhs += rhs; } inline Duration operator-(Duration lhs, Duration rhs) { return lhs -= rhs; } // Multiplicative Operators +// Integer operands must be representable as int64_t. template Duration operator*(Duration lhs, T rhs) { return lhs *= rhs; @@ -375,7 +377,8 @@ constexpr Duration InfiniteDuration(); // Hours() // // Factory functions for constructing `Duration` values from an integral number -// of the unit indicated by the factory function's name. +// of the unit indicated by the factory function's name. The number must be +// representable as int64_t. // // Note: no "Days()" factory function exists because "a day" is ambiguous. // Civil days are not always 24 hours long, and a 24-hour duration often does diff --git a/ci/linux_clang-latest_libcxx_asan_bazel.sh b/ci/linux_clang-latest_libcxx_asan_bazel.sh index 4d1d28a9..07af64d0 100755 --- a/ci/linux_clang-latest_libcxx_asan_bazel.sh +++ b/ci/linux_clang-latest_libcxx_asan_bazel.sh @@ -67,13 +67,21 @@ for std in ${STD}; do --compilation_mode=${compilation_mode} \ --copt="-DDYNAMIC_ANNOTATIONS_ENABLED=1" \ --copt="-DADDRESS_SANITIZER" \ + --copt="-DUNDEFINED_BEHAVIOR_SANITIZER" \ --copt="-fsanitize=address" \ + --copt="-fsanitize=float-divide-by-zero" \ + --copt="-fsanitize=nullability" \ + --copt="-fsanitize=undefined" \ + --copt="-fno-sanitize=vptr" \ --copt=-Werror \ --keep_going \ --linkopt="-fsanitize=address" \ + --linkopt="-fsanitize-link-c++-runtime" \ --show_timestamps \ --test_env="ASAN_SYMBOLIZER_PATH=/opt/llvm/clang/bin/llvm-symbolizer" \ --test_env="TZDIR=/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo" \ + --test_env="UBSAN_OPTIONS=print_stacktrace=1" \ + --test_env="UBSAN_SYMBOLIZER_PATH=/opt/llvm/clang/bin/llvm-symbolizer" \ --test_output=errors \ --test_tag_filters="-benchmark,-noasan" \ ${BAZEL_EXTRA_ARGS:-} -- cgit v1.2.3 From 25597bdfc148e91e27678ec30efa52f4fc8c164f Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 2 Oct 2019 15:20:57 -0700 Subject: Export of internal Abseil changes -- 3e60f355db5afd7a864591d81a6c383b6c0a0780 by Samuel Benzaquen : Internal change PiperOrigin-RevId: 272531442 -- 6d189240b8cebe3a390c730de491156d03049229 by Andy Getzendanner : Fix AtomicHook init-order fiasco under MSVC 2019. On this platform, constexpr static init sometimes happens after dynamic init =/. When it does, we should not zero hook_ (overwriting the value written there by dynamic init); instead we should leave it alone. This works even when constexpr static init goes first since all uses of AtomicHook should have static storage duration and be zero-initialized. https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html PiperOrigin-RevId: 272525226 -- d01b14fc06bc75b41c51976ed32e7c304ea1aab7 by Abseil Team : exclude emscripten from running tests involving long doubles PiperOrigin-RevId: 272497628 GitOrigin-RevId: 3e60f355db5afd7a864591d81a6c383b6c0a0780 Change-Id: I3c8a8f5acaf7652a06ef40cf028ef5d2e142f81b --- absl/base/BUILD.bazel | 14 ++++++++++ absl/base/CMakeLists.txt | 15 ++++++++++ absl/base/internal/atomic_hook.h | 26 ++++++++++++------ absl/base/internal/atomic_hook_test.cc | 24 ++++++++++++++++ absl/base/internal/atomic_hook_test_helper.cc | 29 ++++++++++++++++++++ absl/base/internal/atomic_hook_test_helper.h | 32 ++++++++++++++++++++++ absl/container/internal/hashtablez_sampler.cc | 20 +++++++++++++- absl/container/internal/hashtablez_sampler.h | 2 +- .../hashtablez_sampler_force_weak_definition.cc | 5 ++-- absl/random/exponential_distribution_test.cc | 4 +++ absl/random/internal/iostream_state_saver_test.cc | 2 ++ absl/random/uniform_real_distribution_test.cc | 5 ++++ 12 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 absl/base/internal/atomic_hook_test_helper.cc create mode 100644 absl/base/internal/atomic_hook_test_helper.h (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/BUILD.bazel b/absl/base/BUILD.bazel index 57caa065..1e1f0d2d 100644 --- a/absl/base/BUILD.bazel +++ b/absl/base/BUILD.bazel @@ -207,6 +207,19 @@ cc_library( ], ) +cc_library( + name = "atomic_hook_test_helper", + testonly = 1, + srcs = ["internal/atomic_hook_test_helper.cc"], + hdrs = ["internal/atomic_hook_test_helper.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":atomic_hook", + ":core_headers", + ], +) + cc_test( name = "atomic_hook_test", size = "small", @@ -215,6 +228,7 @@ cc_test( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":atomic_hook", + ":atomic_hook_test_helper", ":core_headers", "@com_google_googletest//:gtest_main", ], diff --git a/absl/base/CMakeLists.txt b/absl/base/CMakeLists.txt index 2f11ef86..51705a5a 100644 --- a/absl/base/CMakeLists.txt +++ b/absl/base/CMakeLists.txt @@ -254,6 +254,19 @@ absl_cc_test( gtest_main ) +absl_cc_library( + NAME + atomic_hook_test_helper + SRCS + "internal/atomic_hook_test_helper.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::atomic_hook + absl::core_headers + TESTONLY +) + absl_cc_test( NAME atomic_hook_test @@ -262,8 +275,10 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS + absl::atomic_hook_test_helper absl::atomic_hook absl::core_headers + gmock gtest_main ) diff --git a/absl/base/internal/atomic_hook.h b/absl/base/internal/atomic_hook.h index 803e9059..09f763d0 100644 --- a/absl/base/internal/atomic_hook.h +++ b/absl/base/internal/atomic_hook.h @@ -11,7 +11,6 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -// #ifndef ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ #define ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ @@ -23,8 +22,10 @@ #ifdef _MSC_FULL_VER #define ABSL_HAVE_WORKING_ATOMIC_POINTER 0 +#define ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT 0 #else #define ABSL_HAVE_WORKING_ATOMIC_POINTER 1 +#define ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT 1 #endif namespace absl { @@ -33,16 +34,17 @@ namespace base_internal { template class AtomicHook; -// AtomicHook is a helper class, templatized on a raw function pointer type, for -// implementing Abseil customization hooks. It is a callable object that -// dispatches to the registered hook. +// `AtomicHook` is a helper class, templatized on a raw function pointer type, +// for implementing Abseil customization hooks. It is a callable object that +// dispatches to the registered hook. Objects of type `AtomicHook` must have +// static or thread storage duration. // // A default constructed object performs a no-op (and returns a default // constructed object) if no hook has been registered. // // Hooks can be pre-registered via constant initialization, for example, -// ABSL_CONST_INIT static AtomicHook my_hook(DefaultAction); -// and then changed at runtime via a call to Store(). +// `ABSL_CONST_INIT static AtomicHook my_hook(DefaultAction);` +// and then changed at runtime via a call to `Store()`. // // Reads and writes guarantee memory_order_acquire/memory_order_release // semantics. @@ -57,12 +59,19 @@ class AtomicHook { // Constructs an object that by default dispatches to/returns the // pre-registered default_fn when no hook has been registered at runtime. -#if ABSL_HAVE_WORKING_ATOMIC_POINTER +#if ABSL_HAVE_WORKING_ATOMIC_POINTER && ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT explicit constexpr AtomicHook(FnPtr default_fn) : hook_(default_fn), default_fn_(default_fn) {} #else + // On MSVC, this function sometimes executes after dynamic initiazliation =(. + // If a non-zero `hook_` has been installed by a dynamic initializer, we want + // to preserve it. If not, `hook_` will be zero initialized and we have no + // need to set it to `kUninitialized`. + // https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html explicit constexpr AtomicHook(FnPtr default_fn) - : hook_(kUninitialized), default_fn_(default_fn) {} + : /* hook_(deliberately omitted), */ default_fn_(default_fn) { + static_assert(kUninitialized == 0, "here we rely on zero-initialization"); + } #endif // Stores the provided function pointer as the value for this hook. @@ -158,6 +167,7 @@ class AtomicHook { }; #undef ABSL_HAVE_WORKING_ATOMIC_POINTER +#undef ABSL_HAVE_WORKING_CONSTEXPR_STATIC_INIT } // namespace base_internal } // namespace absl diff --git a/absl/base/internal/atomic_hook_test.cc b/absl/base/internal/atomic_hook_test.cc index ecc80406..794072ee 100644 --- a/absl/base/internal/atomic_hook_test.cc +++ b/absl/base/internal/atomic_hook_test.cc @@ -14,11 +14,15 @@ #include "absl/base/internal/atomic_hook.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/base/attributes.h" +#include "absl/base/internal/atomic_hook_test_helper.h" namespace { +using ::testing::Eq; + int value = 0; void TestHook(int x) { value = x; } @@ -67,4 +71,24 @@ TEST(AtomicHookTest, WithDefaultFunction) { EXPECT_EQ(value, 2); } +ABSL_CONST_INIT int override_func_calls = 0; +void OverrideFunc() { override_func_calls++; } +static struct OverrideInstaller { + OverrideInstaller() { absl::atomic_hook_internal::func.Store(OverrideFunc); } +} override_installer; + +TEST(AtomicHookTest, DynamicInitFromAnotherTU) { + // MSVC 14.2 doesn't do constexpr static init correctly; in particular it + // tends to sequence static init (i.e. defaults) of `AtomicHook` objects + // after their dynamic init (i.e. overrides), overwriting whatever value was + // written during dynamic init. This regression test validates the fix. + // https://developercommunity.visualstudio.com/content/problem/336946/class-with-constexpr-constructor-not-using-static.html + EXPECT_THAT(absl::atomic_hook_internal::default_func_calls, Eq(0)); + EXPECT_THAT(override_func_calls, Eq(0)); + absl::atomic_hook_internal::func(); + EXPECT_THAT(absl::atomic_hook_internal::default_func_calls, Eq(0)); + EXPECT_THAT(override_func_calls, Eq(1)); + EXPECT_THAT(absl::atomic_hook_internal::func.Load(), Eq(OverrideFunc)); +} + } // namespace diff --git a/absl/base/internal/atomic_hook_test_helper.cc b/absl/base/internal/atomic_hook_test_helper.cc new file mode 100644 index 00000000..fad7a89a --- /dev/null +++ b/absl/base/internal/atomic_hook_test_helper.cc @@ -0,0 +1,29 @@ +// 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/base/internal/atomic_hook_test_helper.h" + +#include "absl/base/attributes.h" +#include "absl/base/internal/atomic_hook.h" + +namespace absl { +namespace atomic_hook_internal { + +ABSL_CONST_INIT absl::base_internal::AtomicHook func(DefaultFunc); +ABSL_CONST_INIT int default_func_calls = 0; +void DefaultFunc() { default_func_calls++; } +void RegisterFunc(VoidF f) { func.Store(f); } + +} // namespace atomic_hook_internal +} // namespace absl diff --git a/absl/base/internal/atomic_hook_test_helper.h b/absl/base/internal/atomic_hook_test_helper.h new file mode 100644 index 00000000..44ff780d --- /dev/null +++ b/absl/base/internal/atomic_hook_test_helper.h @@ -0,0 +1,32 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ABSL_BASE_ATOMIC_HOOK_TEST_HELPER_H_ +#define ABSL_BASE_ATOMIC_HOOK_TEST_HELPER_H_ + +#include "absl/base/internal/atomic_hook.h" + +namespace absl { +namespace atomic_hook_internal { + +using VoidF = void (*)(); +extern absl::base_internal::AtomicHook func; +extern int default_func_calls; +void DefaultFunc(); +void RegisterFunc(VoidF func); + +} // namespace atomic_hook_internal +} // namespace absl + +#endif // ABSL_BASE_ATOMIC_HOOK_TEST_HELPER_H_ diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index d03dd82e..054e8981 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -228,8 +228,26 @@ int64_t HashtablezSampler::Iterate( return dropped_samples_.load(std::memory_order_relaxed); } +static bool ShouldForceSampling() { + enum ForceState { + kDontForce, + kForce, + kUninitialized + }; + ABSL_CONST_INIT static std::atomic global_state{ + kUninitialized}; + ForceState state = global_state.load(std::memory_order_relaxed); + if (ABSL_PREDICT_TRUE(state == kDontForce)) return false; + + if (state == kUninitialized) { + state = AbslContainerInternalSampleEverything() ? kForce : kDontForce; + global_state.store(state, std::memory_order_relaxed); + } + return state == kForce; +} + HashtablezInfo* SampleSlow(int64_t* next_sample) { - if (kAbslContainerInternalSampleEverything) { + if (ABSL_PREDICT_FALSE(ShouldForceSampling())) { *next_sample = 1; return HashtablezSampler::Global().Register(); } diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 41121754..53996bb9 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -280,7 +280,7 @@ void SetHashtablezMaxSamples(int32_t max); // initialization of static storage duration objects. // The definition of this constant is weak, which allows us to inject a // different value for it at link time. -extern "C" const bool kAbslContainerInternalSampleEverything; +extern "C" bool AbslContainerInternalSampleEverything(); } // namespace container_internal } // namespace absl diff --git a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc index 4ca6ffda..984dce5d 100644 --- a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +++ b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -20,8 +20,9 @@ namespace absl { namespace container_internal { // See hashtablez_sampler.h for details. -extern "C" ABSL_ATTRIBUTE_WEAK const bool - kAbslContainerInternalSampleEverything = false; +extern "C" ABSL_ATTRIBUTE_WEAK bool AbslContainerInternalSampleEverything() { + return false; +} } // namespace container_internal } // namespace absl diff --git a/absl/random/exponential_distribution_test.cc b/absl/random/exponential_distribution_test.cc index dc49044d..f3cfd764 100644 --- a/absl/random/exponential_distribution_test.cc +++ b/absl/random/exponential_distribution_test.cc @@ -46,7 +46,11 @@ using absl::random_internal::kChiSquared; template class ExponentialDistributionTypedTest : public ::testing::Test {}; +#if defined(__EMSCRIPTEN__) +using RealTypes = ::testing::Types; +#else using RealTypes = ::testing::Types; +#endif // defined(__EMSCRIPTEN__) TYPED_TEST_CASE(ExponentialDistributionTypedTest, RealTypes); TYPED_TEST(ExponentialDistributionTypedTest, SerializeTest) { diff --git a/absl/random/internal/iostream_state_saver_test.cc b/absl/random/internal/iostream_state_saver_test.cc index 2ecbaac1..722766d0 100644 --- a/absl/random/internal/iostream_state_saver_test.cc +++ b/absl/random/internal/iostream_state_saver_test.cc @@ -272,6 +272,7 @@ TEST(IOStreamStateSaver, RoundTripDoubles) { } } +#if !defined(__EMSCRIPTEN__) TEST(IOStreamStateSaver, RoundTripLongDoubles) { // Technically, C++ only guarantees that long double is at least as large as a // double. Practically it varies from 64-bits to 128-bits. @@ -349,6 +350,7 @@ TEST(IOStreamStateSaver, RoundTripLongDoubles) { } } } +#endif // !defined(__EMSCRIPTEN__) TEST(StrToDTest, DoubleMin) { const char kV[] = "2.22507385850720138e-308"; diff --git a/absl/random/uniform_real_distribution_test.cc b/absl/random/uniform_real_distribution_test.cc index 597f0ee5..9f14d1c5 100644 --- a/absl/random/uniform_real_distribution_test.cc +++ b/absl/random/uniform_real_distribution_test.cc @@ -54,7 +54,12 @@ namespace { template class UniformRealDistributionTest : public ::testing::Test {}; +#if defined(__EMSCRIPTEN__) +using RealTypes = ::testing::Types; +#else using RealTypes = ::testing::Types; +#endif // defined(__EMSCRIPTEN__) + TYPED_TEST_SUITE(UniformRealDistributionTest, RealTypes); TYPED_TEST(UniformRealDistributionTest, ParamSerializeTest) { -- 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/container/internal/hashtablez_sampler.cc') 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/container/internal/hashtablez_sampler.cc') 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 7f4fe64af80fe3c84db8ea938276c3690573c45e Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 25 Nov 2019 10:40:20 -0800 Subject: Export of internal Abseil changes -- 44efc1bb0e0a47eabf0569eaab81c66710d5b9c3 by Mark Barolak : Update "strings::Substitute" to "absl::Substitute" in the absl::Substitute error messages. PiperOrigin-RevId: 282388042 -- 9ec7e9385f5469473f76857dc5b067d869bbc65b by Abseil Team : Remove deprecated ExponentialBiased::Get() PiperOrigin-RevId: 282045123 GitOrigin-RevId: 44efc1bb0e0a47eabf0569eaab81c66710d5b9c3 Change-Id: I915bf0ff5fa7ac2bd5f9fb653d1fbd9ece6af9fc --- absl/base/internal/exponential_biased.cc | 52 ++++++--------------------- absl/base/internal/exponential_biased.h | 6 ---- absl/container/internal/hashtablez_sampler.cc | 6 ++-- absl/strings/substitute.cc | 6 ++-- absl/strings/substitute_test.cc | 6 ++-- 5 files changed, 18 insertions(+), 58 deletions(-) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/internal/exponential_biased.cc b/absl/base/internal/exponential_biased.cc index 3007f9b4..7786c303 100644 --- a/absl/base/internal/exponential_biased.cc +++ b/absl/base/internal/exponential_biased.cc @@ -27,7 +27,16 @@ 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::GetSkipCount(int64_t mean) { if (ABSL_PREDICT_FALSE(!initialized_)) { Initialize(); @@ -63,47 +72,6 @@ int64_t ExponentialBiased::GetStride(int64_t mean) { return GetSkipCount(mean - 1) + 1; } -// 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 = bias_ + (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)) { - // Assume huge values are bias neutral, retain bias for next call. - return std::numeric_limits::max() / 2; - } - int64_t value = std::max(1, std::round(interval)); - bias_ = interval - value; - return value; -} - 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 diff --git a/absl/base/internal/exponential_biased.h b/absl/base/internal/exponential_biased.h index 571505d3..6701e695 100644 --- a/absl/base/internal/exponential_biased.h +++ b/absl/base/internal/exponential_biased.h @@ -96,12 +96,6 @@ class ExponentialBiased { // `GetSkipCount()` depends mostly on what best fits the use case. int64_t GetStride(int64_t mean); - // Generates a rounded exponentially distributed random variable - // by rounding the value to the nearest integer. - // The result will be in the range [0, int64_t max / 2]. - ABSL_DEPRECATED("Use GetSkipCount() or GetStride() instead") - int64_t Get(int64_t mean); - // Computes a random number in the range [0, 1<<(kPrngNumBits+1) - 1] // // This is public to enable testing. diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 4aec0a07..6deeca44 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -196,12 +196,10 @@ HashtablezInfo* SampleSlow(int64_t* next_sample) { return nullptr; #else bool first = *next_sample < 0; - *next_sample = g_exponential_biased_generator.Get( + *next_sample = g_exponential_biased_generator.GetStride( 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; - } + ABSL_ASSERT(*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/strings/substitute.cc b/absl/strings/substitute.cc index 36dbfe7d..5d28c528 100644 --- a/absl/strings/substitute.cc +++ b/absl/strings/substitute.cc @@ -35,7 +35,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, if (i + 1 >= format.size()) { #ifndef NDEBUG ABSL_RAW_LOG(FATAL, - "Invalid strings::Substitute() format std::string: \"%s\".", + "Invalid absl::Substitute() format std::string: \"%s\".", absl::CEscape(format).c_str()); #endif return; @@ -45,7 +45,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, #ifndef NDEBUG ABSL_RAW_LOG( FATAL, - "Invalid strings::Substitute() format std::string: asked for \"$" + "Invalid absl::Substitute() format std::string: asked for \"$" "%d\", but only %d args were given. Full format std::string was: " "\"%s\".", index, static_cast(num_args), absl::CEscape(format).c_str()); @@ -60,7 +60,7 @@ void SubstituteAndAppendArray(std::string* output, absl::string_view format, } else { #ifndef NDEBUG ABSL_RAW_LOG(FATAL, - "Invalid strings::Substitute() format std::string: \"%s\".", + "Invalid absl::Substitute() format std::string: \"%s\".", absl::CEscape(format).c_str()); #endif return; diff --git a/absl/strings/substitute_test.cc b/absl/strings/substitute_test.cc index e27abb17..b005f0f4 100644 --- a/absl/strings/substitute_test.cc +++ b/absl/strings/substitute_test.cc @@ -189,14 +189,14 @@ TEST(SubstituteTest, VectorBoolRef) { TEST(SubstituteDeathTest, SubstituteDeath) { EXPECT_DEBUG_DEATH( static_cast(absl::Substitute(absl::string_view("-$2"), "a", "b")), - "Invalid strings::Substitute\\(\\) format std::string: asked for \"\\$2\", " + "Invalid absl::Substitute\\(\\) format std::string: asked for \"\\$2\", " "but only 2 args were given."); EXPECT_DEBUG_DEATH( static_cast(absl::Substitute("-$z-")), - "Invalid strings::Substitute\\(\\) format std::string: \"-\\$z-\""); + "Invalid absl::Substitute\\(\\) format std::string: \"-\\$z-\""); EXPECT_DEBUG_DEATH( static_cast(absl::Substitute("-$")), - "Invalid strings::Substitute\\(\\) format std::string: \"-\\$\""); + "Invalid absl::Substitute\\(\\) format std::string: \"-\\$\""); } #endif // GTEST_HAS_DEATH_TEST -- 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/container/internal/hashtablez_sampler.cc') 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 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/container/internal/hashtablez_sampler.cc') 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 d936052d32a5b7ca08b0199a6724724aea432309 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 9 Mar 2020 12:34:31 -0700 Subject: Export of internal Abseil changes -- 2c5c118f0615ba90e48ee2f18eccc9f511740f6d by Samuel Benzaquen : Rename internal macros to follow the convention in absl. PiperOrigin-RevId: 299906738 -- 92d84a707c7ebc4ec19bdd92d5765d1b6d218c1e by Derek Mauro : Import GitHub #629: Skip the .exe suffix in the helpshort filter on Windows PiperOrigin-RevId: 299892396 -- 2a6910d4be6c67a8376628764121b528ff53504d by Abseil Team : Use unsigned int128 intrinsic when available. It generates better branchless code. PiperOrigin-RevId: 299848585 -- 110c16cf0a739e1df5028fb6fbd03ef5dde1d278 by Derek Mauro : Import GitHub #594: Avoid reading the registry for Windows UWP apps PiperOrigin-RevId: 299821671 -- d8397d367e88163e5e8a47f379c716352dc91d03 by Greg Falcon : Add absl::Hash support for Cord. The hash function is heterogeneous with other string types: a Cord and a string with the same byte sequence will hash to the same value. SwissTable types know about Cord, and will allow heterogeneous lookup (e.g., you can pass a Cord to flat_hash_map::find(), and vice versa.) Add a missing dependency to the cmake Cord target. PiperOrigin-RevId: 299443713 GitOrigin-RevId: 2c5c118f0615ba90e48ee2f18eccc9f511740f6d Change-Id: I7b087c7984b0cb52c4b337d49266c467b98ebdf9 --- absl/base/internal/sysinfo.cc | 6 +- absl/container/BUILD.bazel | 7 ++ absl/container/CMakeLists.txt | 6 ++ absl/container/btree_benchmark.cc | 6 ++ absl/container/btree_test.cc | 6 ++ absl/container/btree_test.h | 11 +++ absl/container/internal/btree.h | 40 +++++++++- absl/container/internal/hash_function_defaults.h | 15 ++++ .../internal/hash_function_defaults_test.cc | 86 +++++++++++++++++++++- absl/container/internal/hashtablez_sampler.cc | 2 +- absl/container/internal/hashtablez_sampler.h | 2 +- absl/container/internal/hashtablez_sampler_test.cc | 2 +- absl/container/internal/have_sse.h | 19 ++--- absl/container/internal/raw_hash_set.h | 10 +-- absl/hash/BUILD.bazel | 2 + absl/hash/CMakeLists.txt | 2 + absl/hash/hash.h | 1 + absl/hash/hash_test.cc | 49 ++++++++---- absl/hash/internal/hash.h | 21 ++++++ absl/numeric/int128.h | 31 ++++---- absl/strings/CMakeLists.txt | 1 + 21 files changed, 274 insertions(+), 51 deletions(-) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index 2ec57930..72f9f173 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -72,10 +72,10 @@ static int GetNumCPUs() { #if defined(_WIN32) static double GetNominalCPUFrequency() { -// UWP apps don't have access to the registry and currently don't provide an -// API informing about CPU nominal frequency. #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \ !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + // UWP apps don't have access to the registry and currently don't provide an + // API informing about CPU nominal frequency. return 1.0; #else #pragma comment(lib, "advapi32.lib") // For Reg* functions. @@ -97,7 +97,7 @@ static double GetNominalCPUFrequency() { } } return 1.0; -#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP +#endif // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP } #elif defined(CTL_HW) && defined(HW_CPU_FREQ) diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index f2217140..70985641 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -390,6 +390,7 @@ cc_library( "//absl/base:config", "//absl/hash", "//absl/strings", + "//absl/strings:cord", ], ) @@ -402,7 +403,10 @@ cc_test( deps = [ ":hash_function_defaults", "//absl/hash", + "//absl/random", "//absl/strings", + "//absl/strings:cord", + "//absl/strings:cord_test_helpers", "@com_google_googletest//:gtest_main", ], ) @@ -828,6 +832,7 @@ cc_library( "//absl/memory", "//absl/meta:type_traits", "//absl/strings", + "//absl/strings:cord", "//absl/types:compare", "//absl/utility", ], @@ -844,6 +849,7 @@ cc_library( ":btree", ":flat_hash_set", "//absl/strings", + "//absl/strings:cord", "//absl/time", ], ) @@ -895,6 +901,7 @@ cc_binary( "//absl/flags:flag", "//absl/hash", "//absl/memory", + "//absl/strings:cord", "//absl/strings:str_format", "//absl/time", "@com_github_google_benchmark//:benchmark_main", diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index e702ba85..99a8e9c0 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -40,6 +40,7 @@ absl_cc_library( absl::compare absl::compressed_tuple absl::container_memory + absl::cord absl::core_headers absl::layout absl::memory @@ -60,6 +61,7 @@ absl_cc_library( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::btree + absl::cord absl::flat_hash_set absl::strings absl::time @@ -443,6 +445,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::config + absl::cord absl::hash absl::strings PUBLIC @@ -456,8 +459,11 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS + absl::cord + absl::cord_test_helpers absl::hash_function_defaults absl::hash + absl::random_random absl::strings gmock_main ) diff --git a/absl/container/btree_benchmark.cc b/absl/container/btree_benchmark.cc index 420cfa0d..ca4d575c 100644 --- a/absl/container/btree_benchmark.cc +++ b/absl/container/btree_benchmark.cc @@ -36,6 +36,7 @@ #include "absl/flags/flag.h" #include "absl/hash/hash.h" #include "absl/memory/memory.h" +#include "absl/strings/cord.h" #include "absl/strings/str_format.h" #include "absl/time/time.h" #include "benchmark/benchmark.h" @@ -438,6 +439,7 @@ using StdString = std::string; STL_ORDERED_TYPES(int32_t); STL_ORDERED_TYPES(int64_t); STL_ORDERED_TYPES(StdString); +STL_ORDERED_TYPES(Cord); STL_ORDERED_TYPES(Time); #define STL_UNORDERED_TYPES(value) \ @@ -458,6 +460,8 @@ STL_ORDERED_TYPES(Time); using stl_unordered_multimap_##value = \ std::unordered_multimap +STL_UNORDERED_TYPES_CUSTOM_HASH(Cord, absl::Hash); + STL_UNORDERED_TYPES(int32_t); STL_UNORDERED_TYPES(int64_t); STL_UNORDERED_TYPES(StdString); @@ -478,6 +482,7 @@ STL_UNORDERED_TYPES_CUSTOM_HASH(Time, absl::Hash); BTREE_TYPES(int32_t); BTREE_TYPES(int64_t); BTREE_TYPES(StdString); +BTREE_TYPES(Cord); BTREE_TYPES(Time); #define MY_BENCHMARK4(type, func) \ @@ -526,6 +531,7 @@ BTREE_TYPES(Time); MY_BENCHMARK(int32_t); MY_BENCHMARK(int64_t); MY_BENCHMARK(StdString); +MY_BENCHMARK(Cord); MY_BENCHMARK(Time); // Define a type whose size and cost of moving are independently customizable. diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index ce12e819..da8e7082 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc @@ -812,10 +812,12 @@ void MapTest() { TEST(Btree, set_int32) { SetTest(); } TEST(Btree, set_int64) { SetTest(); } TEST(Btree, set_string) { SetTest(); } +TEST(Btree, set_cord) { SetTest(); } TEST(Btree, set_pair) { SetTest>(); } TEST(Btree, map_int32) { MapTest(); } TEST(Btree, map_int64) { MapTest(); } TEST(Btree, map_string) { MapTest(); } +TEST(Btree, map_cord) { MapTest(); } TEST(Btree, map_pair) { MapTest>(); } template @@ -847,10 +849,12 @@ void MultiMapTest() { TEST(Btree, multiset_int32) { MultiSetTest(); } TEST(Btree, multiset_int64) { MultiSetTest(); } TEST(Btree, multiset_string) { MultiSetTest(); } +TEST(Btree, multiset_cord) { MultiSetTest(); } TEST(Btree, multiset_pair) { MultiSetTest>(); } TEST(Btree, multimap_int32) { MultiMapTest(); } TEST(Btree, multimap_int64) { MultiMapTest(); } TEST(Btree, multimap_string) { MultiMapTest(); } +TEST(Btree, multimap_cord) { MultiMapTest(); } TEST(Btree, multimap_pair) { MultiMapTest>(); } struct CompareIntToString { @@ -1268,6 +1272,8 @@ TEST(Btree, KeyCompareToAdapter) { AssertKeyCompareToAdapted, absl::string_view>(); AssertKeyCompareToAdapted, absl::string_view>(); + AssertKeyCompareToAdapted, absl::Cord>(); + AssertKeyCompareToAdapted, absl::Cord>(); AssertKeyCompareToNotAdapted, int>(); AssertKeyCompareToNotAdapted, int>(); } diff --git a/absl/container/btree_test.h b/absl/container/btree_test.h index 218ba41d..62490807 100644 --- a/absl/container/btree_test.h +++ b/absl/container/btree_test.h @@ -25,6 +25,7 @@ #include "absl/container/btree_map.h" #include "absl/container/btree_set.h" #include "absl/container/flat_hash_set.h" +#include "absl/strings/cord.h" #include "absl/time/time.h" namespace absl { @@ -100,6 +101,16 @@ struct Generator { } }; +template <> +struct Generator { + int maxval; + explicit Generator(int m) : maxval(m) {} + Cord operator()(int i) const { + char buf[16]; + return Cord(GenerateDigits(buf, i, maxval)); + } +}; + template struct Generator > { Generator::type> tgen; diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index 2a5c7314..301c3656 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -65,6 +65,7 @@ #include "absl/container/internal/layout.h" #include "absl/memory/memory.h" #include "absl/meta/type_traits.h" +#include "absl/strings/cord.h" #include "absl/strings/string_view.h" #include "absl/types/compare.h" #include "absl/utility/utility.h" @@ -93,6 +94,19 @@ struct StringBtreeDefaultLess { absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(lhs.compare(rhs)); } + StringBtreeDefaultLess(std::less) {} // NOLINT + absl::weak_ordering operator()(const absl::Cord &lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(lhs.Compare(rhs)); + } + absl::weak_ordering operator()(const absl::Cord &lhs, + absl::string_view rhs) const { + return compare_internal::compare_result_as_ordering(lhs.Compare(rhs)); + } + absl::weak_ordering operator()(absl::string_view lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(-rhs.Compare(lhs)); + } }; struct StringBtreeDefaultGreater { @@ -107,13 +121,27 @@ struct StringBtreeDefaultGreater { absl::string_view rhs) const { return compare_internal::compare_result_as_ordering(rhs.compare(lhs)); } + StringBtreeDefaultGreater(std::greater) {} // NOLINT + absl::weak_ordering operator()(const absl::Cord &lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(rhs.Compare(lhs)); + } + absl::weak_ordering operator()(const absl::Cord &lhs, + absl::string_view rhs) const { + return compare_internal::compare_result_as_ordering(-lhs.Compare(rhs)); + } + absl::weak_ordering operator()(absl::string_view lhs, + const absl::Cord &rhs) const { + return compare_internal::compare_result_as_ordering(rhs.Compare(lhs)); + } }; // A helper class to convert a boolean comparison into a three-way "compare-to" // comparison that returns a negative value to indicate less-than, zero to // indicate equality and a positive value to indicate greater-than. This helper // class is specialized for less, greater, -// less, and greater. +// less, greater, less, and +// greater. // // key_compare_to_adapter is provided so that btree users // automatically get the more efficient compare-to code when using common @@ -145,6 +173,16 @@ struct key_compare_to_adapter> { using type = StringBtreeDefaultGreater; }; +template <> +struct key_compare_to_adapter> { + using type = StringBtreeDefaultLess; +}; + +template <> +struct key_compare_to_adapter> { + using type = StringBtreeDefaultGreater; +}; + template struct common_params { diff --git a/absl/container/internal/hash_function_defaults.h b/absl/container/internal/hash_function_defaults.h index 401ddf4d..0683422a 100644 --- a/absl/container/internal/hash_function_defaults.h +++ b/absl/container/internal/hash_function_defaults.h @@ -53,6 +53,7 @@ #include "absl/base/config.h" #include "absl/hash/hash.h" +#include "absl/strings/cord.h" #include "absl/strings/string_view.h" namespace absl { @@ -72,6 +73,9 @@ struct StringHash { size_t operator()(absl::string_view v) const { return absl::Hash{}(v); } + size_t operator()(const absl::Cord& v) const { + return absl::Hash{}(v); + } }; // Supports heterogeneous lookup for string-like elements. @@ -82,6 +86,15 @@ struct StringHashEq { bool operator()(absl::string_view lhs, absl::string_view rhs) const { return lhs == rhs; } + bool operator()(const absl::Cord& lhs, const absl::Cord& rhs) const { + return lhs == rhs; + } + bool operator()(const absl::Cord& lhs, absl::string_view rhs) const { + return lhs == rhs; + } + bool operator()(absl::string_view lhs, const absl::Cord& rhs) const { + return lhs == rhs; + } }; }; @@ -89,6 +102,8 @@ template <> struct HashEq : StringHashEq {}; template <> struct HashEq : StringHashEq {}; +template <> +struct HashEq : StringHashEq {}; // Supports heterogeneous lookup for pointers and smart pointers. template diff --git a/absl/container/internal/hash_function_defaults_test.cc b/absl/container/internal/hash_function_defaults_test.cc index 2eefc7e0..2d05a0b7 100644 --- a/absl/container/internal/hash_function_defaults_test.cc +++ b/absl/container/internal/hash_function_defaults_test.cc @@ -19,6 +19,9 @@ #include #include "gtest/gtest.h" +#include "absl/random/random.h" +#include "absl/strings/cord.h" +#include "absl/strings/cord_test_helpers.h" #include "absl/strings/string_view.h" namespace absl { @@ -203,10 +206,91 @@ TYPED_TEST(HashPointer, Works) { EXPECT_NE(hash(&dummy), hash(cuptr)); } +TEST(EqCord, Works) { + hash_default_eq eq; + const absl::string_view a_string_view = "a"; + const absl::Cord a_cord(a_string_view); + const absl::string_view b_string_view = "b"; + const absl::Cord b_cord(b_string_view); + + EXPECT_TRUE(eq(a_cord, a_cord)); + EXPECT_TRUE(eq(a_cord, a_string_view)); + EXPECT_TRUE(eq(a_string_view, a_cord)); + EXPECT_FALSE(eq(a_cord, b_cord)); + EXPECT_FALSE(eq(a_cord, b_string_view)); + EXPECT_FALSE(eq(b_string_view, a_cord)); +} + +TEST(HashCord, Works) { + hash_default_hash hash; + const absl::string_view a_string_view = "a"; + const absl::Cord a_cord(a_string_view); + const absl::string_view b_string_view = "b"; + const absl::Cord b_cord(b_string_view); + + EXPECT_EQ(hash(a_cord), hash(a_cord)); + EXPECT_EQ(hash(b_cord), hash(b_cord)); + EXPECT_EQ(hash(a_string_view), hash(a_cord)); + EXPECT_EQ(hash(b_string_view), hash(b_cord)); + EXPECT_EQ(hash(absl::Cord("")), hash("")); + EXPECT_EQ(hash(absl::Cord()), hash(absl::string_view())); + + EXPECT_NE(hash(a_cord), hash(b_cord)); + EXPECT_NE(hash(a_cord), hash(b_string_view)); + EXPECT_NE(hash(a_string_view), hash(b_cord)); + EXPECT_NE(hash(a_string_view), hash(b_string_view)); +} + +void NoOpReleaser(absl::string_view data, void* arg) {} + +TEST(HashCord, FragmentedCordWorks) { + hash_default_hash hash; + absl::Cord c = absl::MakeFragmentedCord({"a", "b", "c"}); + EXPECT_FALSE(c.TryFlat().has_value()); + EXPECT_EQ(hash(c), hash("abc")); +} + +TEST(HashCord, FragmentedLongCordWorks) { + hash_default_hash hash; + // Crete some large strings which do not fit on the stack. + std::string a(65536, 'a'); + std::string b(65536, 'b'); + absl::Cord c = absl::MakeFragmentedCord({a, b}); + EXPECT_FALSE(c.TryFlat().has_value()); + EXPECT_EQ(hash(c), hash(a + b)); +} + +TEST(HashCord, RandomCord) { + hash_default_hash hash; + auto bitgen = absl::BitGen(); + for (int i = 0; i < 1000; ++i) { + const int number_of_segments = absl::Uniform(bitgen, 0, 10); + std::vector pieces; + for (size_t s = 0; s < number_of_segments; ++s) { + std::string str; + str.resize(absl::Uniform(bitgen, 0, 4096)); + // MSVC needed the explicit return type in the lambda. + std::generate(str.begin(), str.end(), [&]() -> char { + return static_cast(absl::Uniform(bitgen)); + }); + pieces.push_back(str); + } + absl::Cord c = absl::MakeFragmentedCord(pieces); + EXPECT_EQ(hash(c), hash(std::string(c))); + } +} + // Cartesian product of (std::string, absl::string_view) -// with (std::string, absl::string_view, const char*). +// with (std::string, absl::string_view, const char*, absl::Cord). using StringTypesCartesianProduct = Types< // clang-format off + std::pair, + std::pair, + std::pair, + std::pair, + + std::pair, + std::pair, std::pair, std::pair, diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 56447251..886524f1 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -226,7 +226,7 @@ void RecordInsertSlow(HashtablezInfo* info, size_t hash, // SwissTables probe in groups of 16, so scale this to count items probes and // not offset from desired. size_t probe_length = distance_from_desired; -#if SWISSTABLE_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 probe_length /= 16; #else probe_length /= 8; diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 34d5e572..8aaffc35 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -98,7 +98,7 @@ struct HashtablezInfo { }; inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { -#if SWISSTABLE_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 total_probe_length /= 16; #else total_probe_length /= 8; diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 36f5ccdd..b4c4ff92 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -29,7 +29,7 @@ #include "absl/time/clock.h" #include "absl/time/time.h" -#if SWISSTABLE_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 constexpr int kProbeLength = 16; #else constexpr int kProbeLength = 8; diff --git a/absl/container/internal/have_sse.h b/absl/container/internal/have_sse.h index 43414418..e75e1a16 100644 --- a/absl/container/internal/have_sse.h +++ b/absl/container/internal/have_sse.h @@ -16,33 +16,34 @@ #ifndef ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_ #define ABSL_CONTAINER_INTERNAL_HAVE_SSE_H_ -#ifndef SWISSTABLE_HAVE_SSE2 +#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 #if defined(__SSE2__) || \ (defined(_MSC_VER) && \ (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2))) -#define SWISSTABLE_HAVE_SSE2 1 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 1 #else -#define SWISSTABLE_HAVE_SSE2 0 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 0 #endif #endif -#ifndef SWISSTABLE_HAVE_SSSE3 +#ifndef ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 #ifdef __SSSE3__ -#define SWISSTABLE_HAVE_SSSE3 1 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 1 #else -#define SWISSTABLE_HAVE_SSSE3 0 +#define ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 0 #endif #endif -#if SWISSTABLE_HAVE_SSSE3 && !SWISSTABLE_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 && \ + !ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 #error "Bad configuration!" #endif -#if SWISSTABLE_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 #include #endif -#if SWISSTABLE_HAVE_SSSE3 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 #include #endif diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index ca7be8d8..fb47f62f 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -312,7 +312,7 @@ inline bool IsFull(ctrl_t c) { return c >= 0; } inline bool IsDeleted(ctrl_t c) { return c == kDeleted; } inline bool IsEmptyOrDeleted(ctrl_t c) { return c < kSentinel; } -#if SWISSTABLE_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 // https://github.com/abseil/abseil-cpp/issues/209 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853 @@ -346,7 +346,7 @@ struct GroupSse2Impl { // Returns a bitmask representing the positions of empty slots. BitMask MatchEmpty() const { -#if SWISSTABLE_HAVE_SSSE3 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 // This only works because kEmpty is -128. return BitMask( _mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))); @@ -372,7 +372,7 @@ struct GroupSse2Impl { void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const { auto msbs = _mm_set1_epi8(static_cast(-128)); auto x126 = _mm_set1_epi8(126); -#if SWISSTABLE_HAVE_SSSE3 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSSE3 auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs); #else auto zero = _mm_setzero_si128(); @@ -384,7 +384,7 @@ struct GroupSse2Impl { __m128i ctrl; }; -#endif // SWISSTABLE_HAVE_SSE2 +#endif // ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 struct GroupPortableImpl { static constexpr size_t kWidth = 8; @@ -438,7 +438,7 @@ struct GroupPortableImpl { uint64_t ctrl; }; -#if SWISSTABLE_HAVE_SSE2 +#if ABSL_INTERNAL_RAW_HASH_SET_HAVE_SSE2 using Group = GroupSse2Impl; #else using Group = GroupPortableImpl; diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index ffe8c294..59eac784 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel @@ -43,6 +43,7 @@ cc_library( "//absl/meta:type_traits", "//absl/numeric:int128", "//absl/strings", + "//absl/strings:cord", "//absl/types:optional", "//absl/types:variant", "//absl/utility", @@ -76,6 +77,7 @@ cc_test( "//absl/container:flat_hash_set", "//absl/meta:type_traits", "//absl/numeric:int128", + "//absl/strings:cord_test_helpers", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt index febc551f..4e555147 100644 --- a/absl/hash/CMakeLists.txt +++ b/absl/hash/CMakeLists.txt @@ -25,6 +25,7 @@ absl_cc_library( COPTS ${ABSL_DEFAULT_COPTS} DEPS + absl::cord absl::core_headers absl::endian absl::fixed_array @@ -62,6 +63,7 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS + absl::cord_test_helpers absl::hash absl::hash_testing absl::core_headers diff --git a/absl/hash/hash.h b/absl/hash/hash.h index 23a65ea8..3dbeab69 100644 --- a/absl/hash/hash.h +++ b/absl/hash/hash.h @@ -98,6 +98,7 @@ ABSL_NAMESPACE_BEGIN // * std::tuple, if all the Ts... are hashable // * std::unique_ptr and std::shared_ptr // * All string-like types including: +// * absl::Cord // * std::string // * std::string_view (as well as any instance of std::basic_string that // uses char and std::char_traits) diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index f02a537a..e55e0ca9 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -42,6 +42,7 @@ #include "absl/hash/internal/spy_hash_state.h" #include "absl/meta/type_traits.h" #include "absl/numeric/int128.h" +#include "absl/strings/cord_test_helpers.h" namespace { @@ -269,6 +270,22 @@ struct WrapInTuple { } }; +absl::Cord FlatCord(absl::string_view sv) { + absl::Cord c(sv); + c.Flatten(); + return c; +} + +absl::Cord FragmentedCord(absl::string_view sv) { + if (sv.size() < 2) { + return absl::Cord(sv); + } + size_t halfway = sv.size() / 2; + std::vector parts = {sv.substr(0, halfway), + sv.substr(halfway)}; + return absl::MakeFragmentedCord(parts); +} + TEST(HashValueTest, Strings) { EXPECT_TRUE((is_hashable::value)); @@ -277,23 +294,27 @@ TEST(HashValueTest, Strings) { const std::string large = std::string(2048, 'x'); // multiple of chunk size const std::string huge = std::string(5000, 'a'); // not a multiple - EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( - std::string(), absl::string_view(), - std::string(""), absl::string_view(""), - std::string(small), absl::string_view(small), - std::string(dup), absl::string_view(dup), - std::string(large), absl::string_view(large), - std::string(huge), absl::string_view(huge)))); + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( // + std::string(), absl::string_view(), absl::Cord(), // + std::string(""), absl::string_view(""), absl::Cord(""), // + std::string(small), absl::string_view(small), absl::Cord(small), // + std::string(dup), absl::string_view(dup), absl::Cord(dup), // + std::string(large), absl::string_view(large), absl::Cord(large), // + std::string(huge), absl::string_view(huge), FlatCord(huge), // + FragmentedCord(huge)))); // Also check that nested types maintain the same hash. const WrapInTuple t{}; - EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( - t(std::string()), t(absl::string_view()), - t(std::string("")), t(absl::string_view("")), - t(std::string(small)), t(absl::string_view(small)), - t(std::string(dup)), t(absl::string_view(dup)), - t(std::string(large)), t(absl::string_view(large)), - t(std::string(huge)), t(absl::string_view(huge))))); + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(std::make_tuple( // + t(std::string()), t(absl::string_view()), t(absl::Cord()), // + t(std::string("")), t(absl::string_view("")), t(absl::Cord("")), // + t(std::string(small)), t(absl::string_view(small)), // + t(absl::Cord(small)), // + t(std::string(dup)), t(absl::string_view(dup)), t(absl::Cord(dup)), // + t(std::string(large)), t(absl::string_view(large)), // + t(absl::Cord(large)), // + t(std::string(huge)), t(absl::string_view(huge)), // + t(FlatCord(huge)), t(FragmentedCord(huge))))); // Make sure that hashing a `const char*` does not use its std::string-value. EXPECT_NE(SpyHash(static_cast("ABC")), diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 1cc2c5e5..025d287f 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -43,6 +43,7 @@ #include "absl/container/fixed_array.h" #include "absl/meta/type_traits.h" #include "absl/numeric/int128.h" +#include "absl/strings/cord.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "absl/types/variant.h" @@ -413,6 +414,7 @@ H AbslHashValue(H hash_state, const std::shared_ptr& ptr) { // All the string-like types supported here provide the same hash expansion for // the same character sequence. These types are: // +// - `absl::Cord` // - `std::string` (and std::basic_string, A> for // any allocator A) // - `absl::string_view` and `std::string_view` @@ -441,6 +443,25 @@ H AbslHashValue( str.size()); } +template +H HashFragmentedCord(H hash_state, const absl::Cord& c) { + PiecewiseCombiner combiner; + c.ForEachChunk([&combiner, &hash_state](absl::string_view chunk) { + hash_state = + combiner.add_buffer(std::move(hash_state), chunk.data(), chunk.size()); + }); + return H::combine(combiner.finalize(std::move(hash_state)), c.size()); +} + +template +H AbslHashValue(H hash_state, const absl::Cord& c) { + absl::optional maybe_flat = c.TryFlat(); + if (maybe_flat.has_value()) { + return H::combine(std::move(hash_state), *maybe_flat); + } + return hash_internal::HashFragmentedCord(std::move(hash_state), c); +} + // ----------------------------------------------------------------------------- // AbslHashValue for Sequence Containers // ----------------------------------------------------------------------------- diff --git a/absl/numeric/int128.h b/absl/numeric/int128.h index 636e3a5b..0dd814a8 100644 --- a/absl/numeric/int128.h +++ b/absl/numeric/int128.h @@ -792,28 +792,21 @@ inline bool operator!=(uint128 lhs, uint128 rhs) { } inline bool operator<(uint128 lhs, uint128 rhs) { +#ifdef ABSL_HAVE_INTRINSIC_INT128 + return static_cast(lhs) < + static_cast(rhs); +#else return (Uint128High64(lhs) == Uint128High64(rhs)) ? (Uint128Low64(lhs) < Uint128Low64(rhs)) : (Uint128High64(lhs) < Uint128High64(rhs)); +#endif } -inline bool operator>(uint128 lhs, uint128 rhs) { - return (Uint128High64(lhs) == Uint128High64(rhs)) - ? (Uint128Low64(lhs) > Uint128Low64(rhs)) - : (Uint128High64(lhs) > Uint128High64(rhs)); -} +inline bool operator>(uint128 lhs, uint128 rhs) { return rhs < lhs; } -inline bool operator<=(uint128 lhs, uint128 rhs) { - return (Uint128High64(lhs) == Uint128High64(rhs)) - ? (Uint128Low64(lhs) <= Uint128Low64(rhs)) - : (Uint128High64(lhs) <= Uint128High64(rhs)); -} +inline bool operator<=(uint128 lhs, uint128 rhs) { return !(rhs < lhs); } -inline bool operator>=(uint128 lhs, uint128 rhs) { - return (Uint128High64(lhs) == Uint128High64(rhs)) - ? (Uint128Low64(lhs) >= Uint128Low64(rhs)) - : (Uint128High64(lhs) >= Uint128High64(rhs)); -} +inline bool operator>=(uint128 lhs, uint128 rhs) { return !(lhs < rhs); } // Unary operators. @@ -870,6 +863,9 @@ inline uint128& uint128::operator^=(uint128 other) { // Arithmetic operators. inline uint128 operator<<(uint128 lhs, int amount) { +#ifdef ABSL_HAVE_INTRINSIC_INT128 + return static_cast(lhs) << amount; +#else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. if (amount < 64) { @@ -881,9 +877,13 @@ inline uint128 operator<<(uint128 lhs, int amount) { return lhs; } return MakeUint128(Uint128Low64(lhs) << (amount - 64), 0); +#endif } inline uint128 operator>>(uint128 lhs, int amount) { +#ifdef ABSL_HAVE_INTRINSIC_INT128 + return static_cast(lhs) >> amount; +#else // uint64_t shifts of >= 64 are undefined, so we will need some // special-casing. if (amount < 64) { @@ -895,6 +895,7 @@ inline uint128 operator>>(uint128 lhs, int amount) { return lhs; } return MakeUint128(0, Uint128High64(lhs) >> (amount - 64)); +#endif } inline uint128 operator+(uint128 lhs, uint128 rhs) { diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 0757a9cb..668d722b 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -548,6 +548,7 @@ absl_cc_library( absl::inlined_vector absl::optional absl::raw_logging_internal + absl::strings absl::type_traits PUBLIC ) -- cgit v1.2.3 From 0e9921b75a0fdd639a504ec8443fc1fe801becd7 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 1 Sep 2020 09:39:43 -0700 Subject: Export of internal Abseil changes -- 23500704dd7c2642fad49f88c07ce41ebaab12e4 by Abseil Team : Change fetch_add() to store(1 + load()) As there is only one concurrent writer to the Info struct, we can avoid using the more expensive fetch_add() function. PiperOrigin-RevId: 329523785 -- 79e5018dba2e117ad89b76367165a604b3f24045 by Abseil Team : Record rehash count in hashtablez This will help identify which containers could benefit from a reserve call. PiperOrigin-RevId: 329510552 -- e327e54b805d67556f934fa7f7dc2d4e72fa066a by Abseil Team : Fix -Wsign-compare issues. These lines could theoretically have overflowed in cases of very large stack traces etc. Very unlikely, but this was causing warnings when built with -Wsign-compare, which we intend to enable with Chromium. In none of these three cases is it trivial to switch to a range-based for loop. PiperOrigin-RevId: 329415195 -- 08aca2fc75e8b3ad1201849987b64148fe48f283 by Xiaoyi Zhang : Release absl::StatusOr. PiperOrigin-RevId: 329353348 -- bf4d2a7f8b089e2adf14d32b0e39de0a981005c3 by Xiaoyi Zhang : Internal change PiperOrigin-RevId: 329337031 -- 42fa7d2fb993bbfc344954227cf1eeb801eca065 by Abseil Team : Internal change PiperOrigin-RevId: 329099807 GitOrigin-RevId: 23500704dd7c2642fad49f88c07ce41ebaab12e4 Change-Id: I6713e4ca3bb0ab2ced5e487827ae036ab8ac61f1 --- CMake/AbseilDll.cmake | 3 + absl/container/internal/hashtablez_sampler.cc | 1 + absl/container/internal/hashtablez_sampler.h | 15 +- absl/container/internal/hashtablez_sampler_test.cc | 3 + absl/status/BUILD.bazel | 36 + absl/status/CMakeLists.txt | 33 + absl/status/internal/statusor_internal.h | 399 +++++ absl/status/status.cc | 4 +- absl/status/statusor.cc | 71 + absl/status/statusor.h | 670 ++++++++ absl/status/statusor_test.cc | 1800 ++++++++++++++++++++ 11 files changed, 3031 insertions(+), 4 deletions(-) create mode 100644 absl/status/internal/statusor_internal.h create mode 100644 absl/status/statusor.cc create mode 100644 absl/status/statusor.h create mode 100644 absl/status/statusor_test.cc (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index 7958ace7..cf6a8c9a 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -175,8 +175,11 @@ set(ABSL_INTERNAL_DLL_FILES "random/uniform_real_distribution.h" "random/zipf_distribution.h" "status/internal/status_internal.h" + "status/internal/statusor_internal.h" "status/status.h" "status/status.cc" + "status/statusor.h" + "status/statusor.cc" "status/status_payload_printer.h" "status/status_payload_printer.cc" "strings/ascii.cc" diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 886524f1..e4484fbb 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -67,6 +67,7 @@ void HashtablezInfo::PrepareForSampling() { capacity.store(0, std::memory_order_relaxed); size.store(0, std::memory_order_relaxed); num_erases.store(0, std::memory_order_relaxed); + num_rehashes.store(0, std::memory_order_relaxed); max_probe_length.store(0, std::memory_order_relaxed); total_probe_length.store(0, std::memory_order_relaxed); hashes_bitwise_or.store(0, std::memory_order_relaxed); diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index e140ee00..b2a30c9a 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -73,6 +73,7 @@ struct HashtablezInfo { std::atomic capacity; std::atomic size; std::atomic num_erases; + std::atomic num_rehashes; std::atomic max_probe_length; std::atomic total_probe_length; std::atomic hashes_bitwise_or; @@ -105,6 +106,11 @@ inline void RecordRehashSlow(HashtablezInfo* info, size_t total_probe_length) { #endif info->total_probe_length.store(total_probe_length, std::memory_order_relaxed); info->num_erases.store(0, std::memory_order_relaxed); + // There is only one concurrent writer, so `load` then `store` is sufficient + // instead of using `fetch_add`. + info->num_rehashes.store( + 1 + info->num_rehashes.load(std::memory_order_relaxed), + std::memory_order_relaxed); } inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, @@ -113,7 +119,8 @@ inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, info->capacity.store(capacity, std::memory_order_relaxed); if (size == 0) { // This is a clear, reset the total/num_erases too. - RecordRehashSlow(info, 0); + info->total_probe_length.store(0, std::memory_order_relaxed); + info->num_erases.store(0, std::memory_order_relaxed); } } @@ -122,7 +129,11 @@ void RecordInsertSlow(HashtablezInfo* info, size_t hash, inline void RecordEraseSlow(HashtablezInfo* info) { info->size.fetch_sub(1, std::memory_order_relaxed); - info->num_erases.fetch_add(1, std::memory_order_relaxed); + // There is only one concurrent writer, so `load` then `store` is sufficient + // instead of using `fetch_add`. + info->num_erases.store( + 1 + info->num_erases.load(std::memory_order_relaxed), + std::memory_order_relaxed); } HashtablezInfo* SampleSlow(int64_t* next_sample); diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index b4c4ff92..04a26cb7 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -76,6 +76,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) { EXPECT_EQ(info.capacity.load(), 0); EXPECT_EQ(info.size.load(), 0); EXPECT_EQ(info.num_erases.load(), 0); + EXPECT_EQ(info.num_rehashes.load(), 0); EXPECT_EQ(info.max_probe_length.load(), 0); EXPECT_EQ(info.total_probe_length.load(), 0); EXPECT_EQ(info.hashes_bitwise_or.load(), 0); @@ -95,6 +96,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) { EXPECT_EQ(info.capacity.load(), 0); EXPECT_EQ(info.size.load(), 0); EXPECT_EQ(info.num_erases.load(), 0); + EXPECT_EQ(info.num_rehashes.load(), 0); EXPECT_EQ(info.max_probe_length.load(), 0); EXPECT_EQ(info.total_probe_length.load(), 0); EXPECT_EQ(info.hashes_bitwise_or.load(), 0); @@ -167,6 +169,7 @@ TEST(HashtablezInfoTest, RecordRehash) { EXPECT_EQ(info.size.load(), 2); EXPECT_EQ(info.total_probe_length.load(), 3); EXPECT_EQ(info.num_erases.load(), 0); + EXPECT_EQ(info.num_rehashes.load(), 1); } #if defined(ABSL_HASHTABLEZ_SAMPLE) diff --git a/absl/status/BUILD.bazel b/absl/status/BUILD.bazel index 81fa46c2..189bd73d 100644 --- a/absl/status/BUILD.bazel +++ b/absl/status/BUILD.bazel @@ -65,3 +65,39 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_library( + name = "statusor", + srcs = [ + "internal/statusor_internal.h", + "statusor.cc", + ], + hdrs = [ + "statusor.h", + ], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":status", + "//absl/base:core_headers", + "//absl/base:raw_logging_internal", + "//absl/meta:type_traits", + "//absl/strings", + "//absl/types:variant", + "//absl/utility", + ], +) + +cc_test( + name = "statusor_test", + size = "small", + srcs = ["statusor_test.cc"], + deps = [ + ":status", + ":statusor", + "//absl/base", + "//absl/memory", + "//absl/types:any", + "//absl/utility", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/absl/status/CMakeLists.txt b/absl/status/CMakeLists.txt index b48989d1..66728551 100644 --- a/absl/status/CMakeLists.txt +++ b/absl/status/CMakeLists.txt @@ -52,3 +52,36 @@ absl_cc_test( absl::strings gmock_main ) + +absl_cc_library( + NAME + statusor + HDRS + "statusor.h" + SRCS + "statusor.cc" + "internal/statusor_internal.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::core_headers + absl::raw_logging_internal + absl::type_traits + absl::strings + absl::utility + absl::variant + PUBLIC +) + +absl_cc_test( + NAME + statusor_test + SRCS + "statusor_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::status + absl::statusor + gmock_main +) diff --git a/absl/status/internal/statusor_internal.h b/absl/status/internal/statusor_internal.h new file mode 100644 index 00000000..96e41da5 --- /dev/null +++ b/absl/status/internal/statusor_internal.h @@ -0,0 +1,399 @@ +// Copyright 2020 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ +#define ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ + +#include +#include + +#include "absl/meta/type_traits.h" +#include "absl/status/status.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +template +class ABSL_MUST_USE_RESULT StatusOr; + +namespace internal_statusor { + +// Detects whether `U` has conversion operator to `StatusOr`, i.e. `operator +// StatusOr()`. +template +struct HasConversionOperatorToStatusOr : std::false_type {}; + +template +void test(char (*)[sizeof(std::declval().operator absl::StatusOr())]); + +template +struct HasConversionOperatorToStatusOr(0))> + : std::true_type {}; + +// Detects whether `T` is constructible or convertible from `StatusOr`. +template +using IsConstructibleOrConvertibleFromStatusOr = + absl::disjunction&>, + std::is_constructible&>, + std::is_constructible&&>, + std::is_constructible&&>, + std::is_convertible&, T>, + std::is_convertible&, T>, + std::is_convertible&&, T>, + std::is_convertible&&, T>>; + +// Detects whether `T` is constructible or convertible or assignable from +// `StatusOr`. +template +using IsConstructibleOrConvertibleOrAssignableFromStatusOr = + absl::disjunction, + std::is_assignable&>, + std::is_assignable&>, + std::is_assignable&&>, + std::is_assignable&&>>; + +// Detects whether direct initializing `StatusOr` from `U` is ambiguous, i.e. +// when `U` is `StatusOr` and `T` is constructible or convertible from `V`. +template +struct IsDirectInitializationAmbiguous + : public absl::conditional_t< + std::is_same>, + U>::value, + std::false_type, + IsDirectInitializationAmbiguous< + T, absl::remove_cv_t>>> {}; + +template +struct IsDirectInitializationAmbiguous> + : public IsConstructibleOrConvertibleFromStatusOr {}; + +// Checks against the constraints of the direction initialization, i.e. when +// `StatusOr::StatusOr(U&&)` should participate in overload resolution. +template +using IsDirectInitializationValid = absl::disjunction< + // Short circuits if T is basically U. + std::is_same>>, + absl::negation, + absl::remove_cv_t>>, + std::is_same>>, + std::is_same>>, + IsDirectInitializationAmbiguous>>>; + +// This trait detects whether `StatusOr::operator=(U&&)` is ambiguous, which +// is equivalent to whether all the following conditions are met: +// 1. `U` is `StatusOr`. +// 2. `T` is constructible and assignable from `V`. +// 3. `T` is constructible and assignable from `U` (i.e. `StatusOr`). +// For example, the following code is considered ambiguous: +// (`T` is `bool`, `U` is `StatusOr`, `V` is `bool`) +// StatusOr s1 = true; // s1.ok() && s1.ValueOrDie() == true +// StatusOr s2 = false; // s2.ok() && s2.ValueOrDie() == false +// s1 = s2; // ambiguous, `s1 = s2.ValueOrDie()` or `s1 = bool(s2)`? +template +struct IsForwardingAssignmentAmbiguous + : public absl::conditional_t< + std::is_same>, + U>::value, + std::false_type, + IsForwardingAssignmentAmbiguous< + T, absl::remove_cv_t>>> {}; + +template +struct IsForwardingAssignmentAmbiguous> + : public IsConstructibleOrConvertibleOrAssignableFromStatusOr {}; + +// Checks against the constraints of the forwarding assignment, i.e. whether +// `StatusOr::operator(U&&)` should participate in overload resolution. +template +using IsForwardingAssignmentValid = absl::disjunction< + // Short circuits if T is basically U. + std::is_same>>, + absl::negation, + absl::remove_cv_t>>, + std::is_same>>, + std::is_same>>, + IsForwardingAssignmentAmbiguous>>>; + +class Helper { + public: + // Move type-agnostic error handling to the .cc. + static void HandleInvalidStatusCtorArg(Status*); + static void Crash(const absl::Status& status); +}; + +// Construct an instance of T in `p` through placement new, passing Args... to +// the constructor. +// This abstraction is here mostly for the gcc performance fix. +template +void PlacementNew(void* p, Args&&... args) { +#if defined(__GNUC__) && !defined(__clang__) + // Teach gcc that 'p' cannot be null, fixing code size issues. + if (p == nullptr) __builtin_unreachable(); +#endif + new (p) T(std::forward(args)...); +} + +// Helper base class to hold the data and all operations. +// We move all this to a base class to allow mixing with the appropriate +// TraitsBase specialization. +template +class StatusOrData { + template + friend class StatusOrData; + + public: + StatusOrData() = delete; + + StatusOrData(const StatusOrData& other) { + if (other.ok()) { + MakeValue(other.data_); + MakeStatus(); + } else { + MakeStatus(other.status_); + } + } + + StatusOrData(StatusOrData&& other) noexcept { + if (other.ok()) { + MakeValue(std::move(other.data_)); + MakeStatus(); + } else { + MakeStatus(std::move(other.status_)); + } + } + + template + explicit StatusOrData(const StatusOrData& other) { + if (other.ok()) { + MakeValue(other.data_); + MakeStatus(); + } else { + MakeStatus(other.status_); + } + } + + template + explicit StatusOrData(StatusOrData&& other) { + if (other.ok()) { + MakeValue(std::move(other.data_)); + MakeStatus(); + } else { + MakeStatus(std::move(other.status_)); + } + } + + template + explicit StatusOrData(absl::in_place_t, Args&&... args) + : data_(std::forward(args)...) { + MakeStatus(); + } + + explicit StatusOrData(const T& value) : data_(value) { + MakeStatus(); + } + explicit StatusOrData(T&& value) : data_(std::move(value)) { + MakeStatus(); + } + + template ::value, + int> = 0> + explicit StatusOrData(U&& v) : status_(v) { + EnsureNotOk(); + } + + StatusOrData& operator=(const StatusOrData& other) { + if (this == &other) return *this; + if (other.ok()) + Assign(other.data_); + else + AssignStatus(other.status_); + return *this; + } + + StatusOrData& operator=(StatusOrData&& other) { + if (this == &other) return *this; + if (other.ok()) + Assign(std::move(other.data_)); + else + AssignStatus(std::move(other.status_)); + return *this; + } + + ~StatusOrData() { + if (ok()) { + status_.~Status(); + data_.~T(); + } else { + status_.~Status(); + } + } + + template + void Assign(U&& value) { + if (ok()) { + data_ = std::forward(value); + } else { + MakeValue(std::forward(value)); + status_ = OkStatus(); + } + } + + template + void AssignStatus(U&& v) { + Clear(); + status_ = static_cast(std::forward(v)); + EnsureNotOk(); + } + + bool ok() const { return status_.ok(); } + + protected: + // status_ will always be active after the constructor. + // We make it a union to be able to initialize exactly how we need without + // waste. + // Eg. in the copy constructor we use the default constructor of Status in + // the ok() path to avoid an extra Ref call. + union { + Status status_; + }; + + // data_ is active iff status_.ok()==true + struct Dummy {}; + union { + // When T is const, we need some non-const object we can cast to void* for + // the placement new. dummy_ is that object. + Dummy dummy_; + T data_; + }; + + void Clear() { + if (ok()) data_.~T(); + } + + void EnsureOk() const { + if (ABSL_PREDICT_FALSE(!ok())) Helper::Crash(status_); + } + + void EnsureNotOk() { + if (ABSL_PREDICT_FALSE(ok())) Helper::HandleInvalidStatusCtorArg(&status_); + } + + // Construct the value (ie. data_) through placement new with the passed + // argument. + template + void MakeValue(Arg&&... arg) { + internal_statusor::PlacementNew(&dummy_, std::forward(arg)...); + } + + // Construct the status (ie. status_) through placement new with the passed + // argument. + template + void MakeStatus(Args&&... args) { + internal_statusor::PlacementNew(&status_, + std::forward(args)...); + } +}; + +// Helper base classes to allow implicitly deleted constructors and assignment +// operators in `StatusOr`. For example, `CopyCtorBase` will explicitly delete +// the copy constructor when T is not copy constructible and `StatusOr` will +// inherit that behavior implicitly. +template ::value> +struct CopyCtorBase { + CopyCtorBase() = default; + CopyCtorBase(const CopyCtorBase&) = default; + CopyCtorBase(CopyCtorBase&&) = default; + CopyCtorBase& operator=(const CopyCtorBase&) = default; + CopyCtorBase& operator=(CopyCtorBase&&) = default; +}; + +template +struct CopyCtorBase { + CopyCtorBase() = default; + CopyCtorBase(const CopyCtorBase&) = delete; + CopyCtorBase(CopyCtorBase&&) = default; + CopyCtorBase& operator=(const CopyCtorBase&) = default; + CopyCtorBase& operator=(CopyCtorBase&&) = default; +}; + +template ::value> +struct MoveCtorBase { + MoveCtorBase() = default; + MoveCtorBase(const MoveCtorBase&) = default; + MoveCtorBase(MoveCtorBase&&) = default; + MoveCtorBase& operator=(const MoveCtorBase&) = default; + MoveCtorBase& operator=(MoveCtorBase&&) = default; +}; + +template +struct MoveCtorBase { + MoveCtorBase() = default; + MoveCtorBase(const MoveCtorBase&) = default; + MoveCtorBase(MoveCtorBase&&) = delete; + MoveCtorBase& operator=(const MoveCtorBase&) = default; + MoveCtorBase& operator=(MoveCtorBase&&) = default; +}; + +template ::value&& + std::is_copy_assignable::value> +struct CopyAssignBase { + CopyAssignBase() = default; + CopyAssignBase(const CopyAssignBase&) = default; + CopyAssignBase(CopyAssignBase&&) = default; + CopyAssignBase& operator=(const CopyAssignBase&) = default; + CopyAssignBase& operator=(CopyAssignBase&&) = default; +}; + +template +struct CopyAssignBase { + CopyAssignBase() = default; + CopyAssignBase(const CopyAssignBase&) = default; + CopyAssignBase(CopyAssignBase&&) = default; + CopyAssignBase& operator=(const CopyAssignBase&) = delete; + CopyAssignBase& operator=(CopyAssignBase&&) = default; +}; + +template ::value&& + std::is_move_assignable::value> +struct MoveAssignBase { + MoveAssignBase() = default; + MoveAssignBase(const MoveAssignBase&) = default; + MoveAssignBase(MoveAssignBase&&) = default; + MoveAssignBase& operator=(const MoveAssignBase&) = default; + MoveAssignBase& operator=(MoveAssignBase&&) = default; +}; + +template +struct MoveAssignBase { + MoveAssignBase() = default; + MoveAssignBase(const MoveAssignBase&) = default; + MoveAssignBase(MoveAssignBase&&) = default; + MoveAssignBase& operator=(const MoveAssignBase&) = default; + MoveAssignBase& operator=(MoveAssignBase&&) = delete; +}; + +ABSL_ATTRIBUTE_NORETURN void ThrowBadStatusOrAccess(absl::Status status); + +} // namespace internal_statusor +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STATUS_INTERNAL_STATUSOR_INTERNAL_H_ diff --git a/absl/status/status.cc b/absl/status/status.cc index 0a655736..a27fd8b3 100644 --- a/absl/status/status.cc +++ b/absl/status/status.cc @@ -78,7 +78,7 @@ static int FindPayloadIndexByUrl(const Payloads* payloads, absl::string_view type_url) { if (payloads == nullptr) return -1; - for (int i = 0; i < payloads->size(); ++i) { + for (size_t i = 0; i < payloads->size(); ++i) { if ((*payloads)[i].type_url == type_url) return i; } @@ -167,7 +167,7 @@ void Status::ForEachPayload( bool in_reverse = payloads->size() > 1 && reinterpret_cast(payloads) % 13 > 6; - for (int index = 0; index < payloads->size(); ++index) { + for (size_t index = 0; index < payloads->size(); ++index) { const auto& elem = (*payloads)[in_reverse ? payloads->size() - 1 - index : index]; diff --git a/absl/status/statusor.cc b/absl/status/statusor.cc new file mode 100644 index 00000000..b954b45e --- /dev/null +++ b/absl/status/statusor.cc @@ -0,0 +1,71 @@ +// 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/status/statusor.h" + +#include +#include + +#include "absl/base/internal/raw_logging.h" +#include "absl/status/status.h" +#include "absl/strings/str_cat.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN + +BadStatusOrAccess::BadStatusOrAccess(absl::Status status) + : status_(std::move(status)) {} + +BadStatusOrAccess::~BadStatusOrAccess() = default; +const char* BadStatusOrAccess::what() const noexcept { + return "Bad StatusOr access"; +} + +const absl::Status& BadStatusOrAccess::status() const { return status_; } + +namespace internal_statusor { + +void Helper::HandleInvalidStatusCtorArg(absl::Status* status) { + const char* kMessage = + "An OK status is not a valid constructor argument to StatusOr"; +#ifdef NDEBUG + ABSL_INTERNAL_LOG(ERROR, kMessage); +#else + ABSL_INTERNAL_LOG(FATAL, kMessage); +#endif + // In optimized builds, we will fall back to InternalError. + *status = absl::InternalError(kMessage); +} + +void Helper::Crash(const absl::Status& status) { + ABSL_INTERNAL_LOG( + FATAL, + absl::StrCat("Attempting to fetch value instead of handling error ", + status.ToString())); +} + +void ThrowBadStatusOrAccess(absl::Status status) { +#ifdef ABSL_HAVE_EXCEPTIONS + throw absl::BadStatusOrAccess(std::move(status)); +#else + ABSL_INTERNAL_LOG( + FATAL, + absl::StrCat("Attempting to fetch value instead of handling error ", + status.ToString())); + std::abort(); +#endif +} + +} // namespace internal_statusor +ABSL_NAMESPACE_END +} // namespace absl diff --git a/absl/status/statusor.h b/absl/status/statusor.h new file mode 100644 index 00000000..95f99f4d --- /dev/null +++ b/absl/status/statusor.h @@ -0,0 +1,670 @@ +// 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. +// +// StatusOr is the union of a Status object and a T +// object. StatusOr models the concept of an object that is either a +// usable value, or an error Status explaining why such a value is +// not present. To this end, StatusOr does not allow its Status +// value to be absl::OkStatus(). +// +// The primary use-case for StatusOr is as the return value of a +// function which may fail. +// +// Example usage of a StatusOr: +// +// StatusOr result = DoBigCalculationThatCouldFail(); +// if (result.ok()) { +// result->DoSomethingCool(); +// } else { +// LOG(ERROR) << result.status(); +// } +// +// Example that is guaranteed to crash if the result holds no value: +// +// StatusOr result = DoBigCalculationThatCouldFail(); +// const Foo& foo = result.value(); +// foo.DoSomethingCool(); +// +// Example usage of a StatusOr>: +// +// StatusOr> result = FooFactory::MakeNewFoo(arg); +// if (!result.ok()) { // Don't omit .ok() +// LOG(ERROR) << result.status(); +// } else if (*result == nullptr) { +// LOG(ERROR) << "Unexpected null pointer"; +// } else { +// (*result)->DoSomethingCool(); +// } +// +// Example factory implementation returning StatusOr: +// +// StatusOr FooFactory::MakeFoo(int arg) { +// if (arg <= 0) { +// return absl::Status(absl::StatusCode::kInvalidArgument, +// "Arg must be positive"); +// } +// return Foo(arg); +// } +// +// NULL POINTERS +// +// Historically StatusOr treated null pointers specially. This is no longer +// true -- a StatusOr can be constructed from a null pointer like any other +// pointer value, and the result will be that ok() returns true and value() +// returns null. + +#ifndef ABSL_STATUS_STATUSOR_H_ +#define ABSL_STATUS_STATUSOR_H_ + +#include +#include +#include +#include +#include +#include + +#include "absl/base/attributes.h" +#include "absl/meta/type_traits.h" +#include "absl/status/internal/statusor_internal.h" +#include "absl/status/status.h" +#include "absl/types/variant.h" +#include "absl/utility/utility.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +class BadStatusOrAccess : public std::exception { + public: + explicit BadStatusOrAccess(absl::Status status); + ~BadStatusOrAccess() override; + const char* what() const noexcept override; + const absl::Status& status() const; + + private: + absl::Status status_; +}; + +// Returned StatusOr objects may not be ignored. +template +class ABSL_MUST_USE_RESULT StatusOr; + +template +class StatusOr : private internal_statusor::StatusOrData, + private internal_statusor::CopyCtorBase, + private internal_statusor::MoveCtorBase, + private internal_statusor::CopyAssignBase, + private internal_statusor::MoveAssignBase { + template + friend class StatusOr; + + typedef internal_statusor::StatusOrData Base; + + public: + typedef T value_type; + + // Constructs a new StatusOr with Status::UNKNOWN status. This is marked + // 'explicit' to try to catch cases like 'return {};', where people think + // absl::StatusOr> will be initialized with an empty vector, + // instead of a Status::UNKNOWN status. + explicit StatusOr(); + + // StatusOr is copy constructible if T is copy constructible. + StatusOr(const StatusOr&) = default; + // StatusOr is copy assignable if T is copy constructible and copy + // assignable. + StatusOr& operator=(const StatusOr&) = default; + + // StatusOr is move constructible if T is move constructible. + StatusOr(StatusOr&&) = default; + // StatusOr is moveAssignable if T is move constructible and move + // assignable. + StatusOr& operator=(StatusOr&&) = default; + + // Converting constructors from StatusOr, when T is constructible from U. + // To avoid ambiguity, they are disabled if T is also constructible from + // StatusOr. Explicit iff the corresponding construction of T from U is + // explicit. + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation>, + std::is_constructible, + std::is_convertible, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr(const StatusOr& other) // NOLINT + : Base(static_cast::Base&>(other)) {} + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation>, + std::is_constructible, + absl::negation>, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + explicit StatusOr(const StatusOr& other) + : Base(static_cast::Base&>(other)) {} + + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation>, std::is_constructible, + std::is_convertible, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr(StatusOr&& other) // NOLINT + : Base(static_cast::Base&&>(other)) {} + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation>, std::is_constructible, + absl::negation>, + absl::negation< + internal_statusor::IsConstructibleOrConvertibleFromStatusOr< + T, U>>>::value, + int> = 0> + explicit StatusOr(StatusOr&& other) + : Base(static_cast::Base&&>(other)) {} + + // Conversion copy/move assignment operator, T must be constructible and + // assignable from U. Only enable if T cannot be directly assigned from + // StatusOr. + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation>, + std::is_constructible, + std::is_assignable, + absl::negation< + internal_statusor:: + IsConstructibleOrConvertibleOrAssignableFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr& operator=(const StatusOr& other) { + this->Assign(other); + return *this; + } + template < + typename U, + absl::enable_if_t< + absl::conjunction< + absl::negation>, std::is_constructible, + std::is_assignable, + absl::negation< + internal_statusor:: + IsConstructibleOrConvertibleOrAssignableFromStatusOr< + T, U>>>::value, + int> = 0> + StatusOr& operator=(StatusOr&& other) { + this->Assign(std::move(other)); + return *this; + } + + // Constructs a new StatusOr with a non-ok status. After calling this + // constructor, this->ok() will be false and calls to value() will CHECK-fail. + // The constructor also takes any type `U` that is convertible to `Status`. + // + // NOTE: Not explicit - we want to use StatusOr as a return + // value, so it is convenient and sensible to be able to do + // `return Status()` or `return ConvertibleToStatus()` when the return type + // is `StatusOr`. + // + // REQUIRES: !Status(std::forward(v)).ok(). This requirement is DCHECKed. + // In optimized builds, passing absl::OkStatus() here will have the effect + // of passing absl::StatusCode::kInternal as a fallback. + template < + typename U = absl::Status, + absl::enable_if_t< + absl::conjunction< + std::is_convertible, + std::is_constructible, + absl::negation, absl::StatusOr>>, + absl::negation, T>>, + absl::negation, absl::in_place_t>>, + absl::negation>>::value, + int> = 0> + StatusOr(U&& v) : Base(std::forward(v)) {} + + template < + typename U = absl::Status, + absl::enable_if_t< + absl::conjunction< + absl::negation>, + std::is_constructible, + absl::negation, absl::StatusOr>>, + absl::negation, T>>, + absl::negation, absl::in_place_t>>, + absl::negation>>::value, + int> = 0> + explicit StatusOr(U&& v) : Base(std::forward(v)) {} + + template < + typename U = absl::Status, + absl::enable_if_t< + absl::conjunction< + std::is_convertible, + std::is_constructible, + absl::negation, absl::StatusOr>>, + absl::negation, T>>, + absl::negation, absl::in_place_t>>, + absl::negation>>::value, + int> = 0> + StatusOr& operator=(U&& v) { + this->AssignStatus(std::forward(v)); + return *this; + } + + // Perfect-forwarding value assignment operator. + // If `*this` contains a `T` value before the call, the contained value is + // assigned from `std::forward(v)`; Otherwise, it is directly-initialized + // from `std::forward(v)`. + // This function does not participate in overload unless: + // 1. `std::is_constructible_v` is true, + // 2. `std::is_assignable_v` is true. + // 3. `std::is_same_v, std::remove_cvref_t>` is false. + // 4. Assigning `U` to `T` is not ambiguous: + // If `U` is `StatusOr` and `T` is constructible and assignable from + // both `StatusOr` and `V`, the assignment is considered bug-prone and + // ambiguous thus will fail to compile. For example: + // StatusOr s1 = true; // s1.ok() && *s1 == true + // StatusOr s2 = false; // s2.ok() && *s2 == false + // s1 = s2; // ambiguous, `s1 = *s2` or `s1 = bool(s2)`? + template < + typename U = T, + typename = typename std::enable_if, std::is_assignable, + absl::disjunction< + std::is_same>, T>, + absl::conjunction< + absl::negation>, + absl::negation>>>, + internal_statusor::IsForwardingAssignmentValid>::value>::type> + StatusOr& operator=(U&& v) { + static_assert( + !absl::conjunction< + std::is_constructible, std::is_assignable, + std::is_constructible, + std::is_assignable, + absl::negation>>>>::value, + "U can assign to both T and Status, will result in semantic change"); + static_assert( + !absl::conjunction< + std::is_constructible, std::is_assignable, + internal_statusor::HasConversionOperatorToStatusOr, + absl::negation>>>>::value, + "U can assign to T and convert to StatusOr, will result in semantic " + "change"); + this->Assign(std::forward(v)); + return *this; + } + + // Constructs the inner value T in-place using the provided args, using the + // T(args...) constructor. + template + explicit StatusOr(absl::in_place_t, Args&&... args); + template + explicit StatusOr(absl::in_place_t, std::initializer_list ilist, + Args&&... args); + + // Constructs the inner value T in-place using the provided args, using the + // T(U) (direct-initialization) constructor. Only valid if T can be + // constructed from a U. Can accept move or copy constructors. Explicit if + // U is not convertible to T. To avoid ambiguity, this is disabled if U is + // a StatusOr, where J is convertible to T. + template < + typename U = T, + absl::enable_if_t< + absl::conjunction< + internal_statusor::IsDirectInitializationValid, + std::is_constructible, std::is_convertible, + absl::disjunction< + std::is_same>, + T>, + absl::conjunction< + absl::negation>, + absl::negation< + internal_statusor::HasConversionOperatorToStatusOr< + T, U&&>>>>>::value, + int> = 0> + StatusOr(U&& u) // NOLINT + : StatusOr(absl::in_place, std::forward(u)) { + static_assert( + !absl::conjunction< + std::is_convertible, std::is_convertible, + absl::negation>>>>::value, + "U is convertible to both T and Status, will result in semantic " + "change"); + static_assert( + !absl::conjunction< + std::is_convertible, + internal_statusor::HasConversionOperatorToStatusOr, + absl::negation>>>>::value, + "U can construct T and convert to StatusOr, will result in semantic " + "change"); + } + + template < + typename U = T, + absl::enable_if_t< + absl::conjunction< + internal_statusor::IsDirectInitializationValid, + absl::disjunction< + std::is_same>, + T>, + absl::conjunction< + absl::negation>, + absl::negation< + internal_statusor::HasConversionOperatorToStatusOr< + T, U&&>>>>, + std::is_constructible, + absl::negation>>::value, + int> = 0> + explicit StatusOr(U&& u) // NOLINT + : StatusOr(absl::in_place, std::forward(u)) { + static_assert( + !absl::conjunction< + std::is_constructible, + std::is_constructible, + absl::negation>>>>::value, + "U can construct both T and Status, will result in semantic " + "change"); + static_assert( + !absl::conjunction< + std::is_constructible, + internal_statusor::HasConversionOperatorToStatusOr, + absl::negation>>>>::value, + "U can construct T and convert to StatusOr, will result in semantic " + "change"); + } + + // Returns this->status().ok() + ABSL_MUST_USE_RESULT bool ok() const { return this->status_.ok(); } + + // Returns a reference to our status. If this contains a T, then + // returns absl::OkStatus(). + const Status& status() const &; + Status status() &&; + + // Returns a reference to the held value if `this->ok()`. Otherwise, throws + // `absl::BadStatusOrAccess` if exception is enabled, or `LOG(FATAL)` if + // exception is disabled. + // If you have already checked the status using `this->ok()`, you probably + // want to use `operator*()` or `operator->()` to access the value instead of + // `value`. + // Note: for value types that are cheap to copy, prefer simple code: + // + // T value = statusor.value(); + // + // Otherwise, if the value type is expensive to copy, but can be left + // in the StatusOr, simply assign to a reference: + // + // T& value = statusor.value(); // or `const T&` + // + // Otherwise, if the value type supports an efficient move, it can be + // used as follows: + // + // T value = std::move(statusor).value(); + // + // The `std::move` on statusor instead of on the whole expression enables + // warnings about possible uses of the statusor object after the move. + const T& value() const&; + T& value() &; + const T&& value() const&&; + T&& value() &&; + + // Returns a reference to the current value. + // + // REQUIRES: this->ok() == true, otherwise the behavior is undefined. + // + // Use this->ok() to verify that there is a current value. + // Alternatively, see value() for a similar API that guarantees + // CHECK-failing if there is no current value. + const T& operator*() const&; + T& operator*() &; + const T&& operator*() const&&; + T&& operator*() &&; + + // Returns a pointer to the current value. + // + // REQUIRES: this->ok() == true, otherwise the behavior is undefined. + // + // Use this->ok() to verify that there is a current value. + const T* operator->() const; + T* operator->(); + + // Returns the current value this->ok() == true. Otherwise constructs a value + // using `default_value`. + // + // Unlike `value`, this function returns by value, copying the current value + // if necessary. If the value type supports an efficient move, it can be used + // as follows: + // + // T value = std::move(statusor).value_or(def); + // + // Unlike with `value`, calling `std::move` on the result of `value_or` will + // still trigger a copy. + template + T value_or(U&& default_value) const&; + template + T value_or(U&& default_value) &&; + + // Ignores any errors. This method does nothing except potentially suppress + // complaints from any tools that are checking that errors are not dropped on + // the floor. + void IgnoreError() const; + + // Reconstructs the inner value T in-place using the provided args, using the + // T(args...) constructor. Returns reference to the reconstructed `T`. + template + T& emplace(Args&&... args) { + if (ok()) { + this->Clear(); + this->MakeValue(std::forward(args)...); + } else { + this->MakeValue(std::forward(args)...); + this->status_ = absl::OkStatus(); + } + return this->data_; + } + + template < + typename U, typename... Args, + absl::enable_if_t< + std::is_constructible&, Args&&...>::value, + int> = 0> + T& emplace(std::initializer_list ilist, Args&&... args) { + if (ok()) { + this->Clear(); + this->MakeValue(ilist, std::forward(args)...); + } else { + this->MakeValue(ilist, std::forward(args)...); + this->status_ = absl::OkStatus(); + } + return this->data_; + } + + private: + using internal_statusor::StatusOrData::Assign; + template + void Assign(const absl::StatusOr& other); + template + void Assign(absl::StatusOr&& other); +}; + +template +bool operator==(const StatusOr& lhs, const StatusOr& rhs) { + if (lhs.ok() && rhs.ok()) return *lhs == *rhs; + return lhs.status() == rhs.status(); +} + +template +bool operator!=(const StatusOr& lhs, const StatusOr& rhs) { + return !(lhs == rhs); +} + +//////////////////////////////////////////////////////////////////////////////// +// Implementation details for StatusOr + +// TODO(sbenza): avoid the string here completely. +template +StatusOr::StatusOr() : Base(Status(absl::StatusCode::kUnknown, "")) {} + +template +template +inline void StatusOr::Assign(const StatusOr& other) { + if (other.ok()) { + this->Assign(*other); + } else { + this->AssignStatus(other.status()); + } +} + +template +template +inline void StatusOr::Assign(StatusOr&& other) { + if (other.ok()) { + this->Assign(*std::move(other)); + } else { + this->AssignStatus(std::move(other).status()); + } +} +template +template +StatusOr::StatusOr(absl::in_place_t, Args&&... args) + : Base(absl::in_place, std::forward(args)...) {} + +template +template +StatusOr::StatusOr(absl::in_place_t, std::initializer_list ilist, + Args&&... args) + : Base(absl::in_place, ilist, std::forward(args)...) {} + +template +const Status& StatusOr::status() const & { return this->status_; } +template +Status StatusOr::status() && { + return ok() ? OkStatus() : std::move(this->status_); +} + +template +const T& StatusOr::value() const& { + if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_); + return this->data_; +} + +template +T& StatusOr::value() & { + if (!this->ok()) internal_statusor::ThrowBadStatusOrAccess(this->status_); + return this->data_; +} + +template +const T&& StatusOr::value() const&& { + if (!this->ok()) { + internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_)); + } + return std::move(this->data_); +} + +template +T&& StatusOr::value() && { + if (!this->ok()) { + internal_statusor::ThrowBadStatusOrAccess(std::move(this->status_)); + } + return std::move(this->data_); +} + +template +const T& StatusOr::operator*() const& { + this->EnsureOk(); + return this->data_; +} + +template +T& StatusOr::operator*() & { + this->EnsureOk(); + return this->data_; +} + +template +const T&& StatusOr::operator*() const&& { + this->EnsureOk(); + return std::move(this->data_); +} + +template +T&& StatusOr::operator*() && { + this->EnsureOk(); + return std::move(this->data_); +} + +template +const T* StatusOr::operator->() const { + this->EnsureOk(); + return &this->data_; +} + +template +T* StatusOr::operator->() { + this->EnsureOk(); + return &this->data_; +} + +template +template +T StatusOr::value_or(U&& default_value) const& { + if (ok()) { + return this->data_; + } + return std::forward(default_value); +} + +template +template +T StatusOr::value_or(U&& default_value) && { + if (ok()) { + return std::move(this->data_); + } + return std::forward(default_value); +} + +template +void StatusOr::IgnoreError() const { + // no-op +} + +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_STATUS_STATUSOR_H_ diff --git a/absl/status/statusor_test.cc b/absl/status/statusor_test.cc new file mode 100644 index 00000000..5e4b2687 --- /dev/null +++ b/absl/status/statusor_test.cc @@ -0,0 +1,1800 @@ +// 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/status/statusor.h" + +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/casts.h" +#include "absl/memory/memory.h" +#include "absl/status/status.h" +#include "absl/types/any.h" +#include "absl/utility/utility.h" + +namespace { + +using ::testing::AllOf; +using ::testing::AnyWith; +using ::testing::ElementsAre; +using ::testing::Field; +using ::testing::Ne; +using ::testing::Not; +using ::testing::Pointee; +using ::testing::VariantWith; + +#ifdef GTEST_HAS_STATUS_MATCHERS +using ::testing::status::IsOk; +using ::testing::status::IsOkAndHolds; +#else // GTEST_HAS_STATUS_MATCHERS +inline const ::absl::Status& GetStatus(const ::absl::Status& status) { + return status; +} + +template +inline const ::absl::Status& GetStatus(const ::absl::StatusOr& status) { + return status.status(); +} + +// Monomorphic implementation of matcher IsOkAndHolds(m). StatusOrType is a +// reference to StatusOr. +template +class IsOkAndHoldsMatcherImpl + : public ::testing::MatcherInterface { + public: + typedef + typename std::remove_reference::type::value_type value_type; + + template + explicit IsOkAndHoldsMatcherImpl(InnerMatcher&& inner_matcher) + : inner_matcher_(::testing::SafeMatcherCast( + std::forward(inner_matcher))) {} + + void DescribeTo(std::ostream* os) const override { + *os << "is OK and has a value that "; + inner_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const override { + *os << "isn't OK or has a value that "; + inner_matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain( + StatusOrType actual_value, + ::testing::MatchResultListener* result_listener) const override { + if (!actual_value.ok()) { + *result_listener << "which has status " << actual_value.status(); + return false; + } + + ::testing::StringMatchResultListener inner_listener; + const bool matches = + inner_matcher_.MatchAndExplain(*actual_value, &inner_listener); + const std::string inner_explanation = inner_listener.str(); + if (!inner_explanation.empty()) { + *result_listener << "which contains value " + << ::testing::PrintToString(*actual_value) << ", " + << inner_explanation; + } + return matches; + } + + private: + const ::testing::Matcher inner_matcher_; +}; + +// Implements IsOkAndHolds(m) as a polymorphic matcher. +template +class IsOkAndHoldsMatcher { + public: + explicit IsOkAndHoldsMatcher(InnerMatcher inner_matcher) + : inner_matcher_(std::move(inner_matcher)) {} + + // Converts this polymorphic matcher to a monomorphic matcher of the + // given type. StatusOrType can be either StatusOr or a + // reference to StatusOr. + template + operator ::testing::Matcher() const { // NOLINT + return ::testing::Matcher( + new IsOkAndHoldsMatcherImpl(inner_matcher_)); + } + + private: + const InnerMatcher inner_matcher_; +}; + +// Monomorphic implementation of matcher IsOk() for a given type T. +// T can be Status, StatusOr<>, or a reference to either of them. +template +class MonoIsOkMatcherImpl : public ::testing::MatcherInterface { + public: + void DescribeTo(std::ostream* os) const override { *os << "is OK"; } + void DescribeNegationTo(std::ostream* os) const override { + *os << "is not OK"; + } + bool MatchAndExplain(T actual_value, + ::testing::MatchResultListener*) const override { + return GetStatus(actual_value).ok(); + } +}; + +// Implements IsOk() as a polymorphic matcher. +class IsOkMatcher { + public: + template + operator ::testing::Matcher() const { // NOLINT + return ::testing::Matcher(new MonoIsOkMatcherImpl()); + } +}; + +// Macros for testing the results of functions that return absl::Status or +// absl::StatusOr (for any type T). +#define EXPECT_OK(expression) EXPECT_THAT(expression, IsOk()) + +// Returns a gMock matcher that matches a StatusOr<> whose status is +// OK and whose value matches the inner matcher. +template +IsOkAndHoldsMatcher::type> IsOkAndHolds( + InnerMatcher&& inner_matcher) { + return IsOkAndHoldsMatcher::type>( + std::forward(inner_matcher)); +} + +// Returns a gMock matcher that matches a Status or StatusOr<> which is OK. +inline IsOkMatcher IsOk() { return IsOkMatcher(); } +#endif // GTEST_HAS_STATUS_MATCHERS + +struct CopyDetector { + CopyDetector() = default; + explicit CopyDetector(int xx) : x(xx) {} + CopyDetector(CopyDetector&& d) noexcept + : x(d.x), copied(false), moved(true) {} + CopyDetector(const CopyDetector& d) : x(d.x), copied(true), moved(false) {} + CopyDetector& operator=(const CopyDetector& c) { + x = c.x; + copied = true; + moved = false; + return *this; + } + CopyDetector& operator=(CopyDetector&& c) noexcept { + x = c.x; + copied = false; + moved = true; + return *this; + } + int x = 0; + bool copied = false; + bool moved = false; +}; + +testing::Matcher CopyDetectorHas(int a, bool b, bool c) { + return AllOf(Field(&CopyDetector::x, a), Field(&CopyDetector::moved, b), + Field(&CopyDetector::copied, c)); +} + +class Base1 { + public: + virtual ~Base1() {} + int pad; +}; + +class Base2 { + public: + virtual ~Base2() {} + int yetotherpad; +}; + +class Derived : public Base1, public Base2 { + public: + virtual ~Derived() {} + int evenmorepad; +}; + +class CopyNoAssign { + public: + explicit CopyNoAssign(int value) : foo(value) {} + CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {} + int foo; + + private: + const CopyNoAssign& operator=(const CopyNoAssign&); +}; + +absl::StatusOr> ReturnUniquePtr() { + // Uses implicit constructor from T&& + return absl::make_unique(0); +} + +TEST(StatusOr, ElementType) { + static_assert(std::is_same::value_type, int>(), ""); + static_assert(std::is_same::value_type, char>(), ""); +} + +TEST(StatusOr, TestMoveOnlyInitialization) { + absl::StatusOr> thing(ReturnUniquePtr()); + ASSERT_TRUE(thing.ok()); + EXPECT_EQ(0, **thing); + int* previous = thing->get(); + + thing = ReturnUniquePtr(); + EXPECT_TRUE(thing.ok()); + EXPECT_EQ(0, **thing); + EXPECT_NE(previous, thing->get()); +} + +TEST(StatusOr, TestMoveOnlyValueExtraction) { + absl::StatusOr> thing(ReturnUniquePtr()); + ASSERT_TRUE(thing.ok()); + std::unique_ptr ptr = *std::move(thing); + EXPECT_EQ(0, *ptr); + + thing = std::move(ptr); + ptr = std::move(*thing); + EXPECT_EQ(0, *ptr); +} + +TEST(StatusOr, TestMoveOnlyInitializationFromTemporaryByValueOrDie) { + std::unique_ptr ptr(*ReturnUniquePtr()); + EXPECT_EQ(0, *ptr); +} + +TEST(StatusOr, TestValueOrDieOverloadForConstTemporary) { + static_assert( + std::is_same&&>().value())>(), + "value() for const temporaries should return const T&&"); +} + +TEST(StatusOr, TestMoveOnlyConversion) { + absl::StatusOr> const_thing(ReturnUniquePtr()); + EXPECT_TRUE(const_thing.ok()); + EXPECT_EQ(0, **const_thing); + + // Test rvalue converting assignment + const int* const_previous = const_thing->get(); + const_thing = ReturnUniquePtr(); + EXPECT_TRUE(const_thing.ok()); + EXPECT_EQ(0, **const_thing); + EXPECT_NE(const_previous, const_thing->get()); +} + +TEST(StatusOr, TestMoveOnlyVector) { + // Sanity check that absl::StatusOr works in vector. + std::vector>> vec; + vec.push_back(ReturnUniquePtr()); + vec.resize(2); + auto another_vec = std::move(vec); + EXPECT_EQ(0, **another_vec[0]); + EXPECT_EQ(absl::UnknownError(""), another_vec[1].status()); +} + +TEST(StatusOr, TestDefaultCtor) { + absl::StatusOr thing; + EXPECT_FALSE(thing.ok()); + EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown); +} + +// Define `EXPECT_DEATH_OR_THROW` to test the behavior of `StatusOr::value`, +// which either throws `BadStatusOrAccess` or `LOG(FATAL)` based on whether +// exceptions are enabled. +#ifdef ABSL_HAVE_EXCEPTIONS +#define EXPECT_DEATH_OR_THROW(statement, status_) \ + EXPECT_THROW( \ + { \ + try { \ + statement; \ + } catch (const absl::BadStatusOrAccess& e) { \ + EXPECT_EQ(e.status(), status_); \ + throw; \ + } \ + }, \ + absl::BadStatusOrAccess); +#else // ABSL_HAVE_EXCEPTIONS +#define EXPECT_DEATH_OR_THROW(statement, status) \ + EXPECT_DEATH_IF_SUPPORTED(statement, status.ToString()); +#endif // ABSL_HAVE_EXCEPTIONS + +TEST(StatusOrDeathTest, TestDefaultCtorValue) { + absl::StatusOr thing; + EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError("")); + const absl::StatusOr thing2; + EXPECT_DEATH_OR_THROW(thing2.value(), absl::UnknownError("")); +} + +TEST(StatusOrDeathTest, TestValueNotOk) { + absl::StatusOr thing(absl::CancelledError()); + EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError()); +} + +TEST(StatusOrDeathTest, TestValueNotOkConst) { + const absl::StatusOr thing(absl::UnknownError("")); + EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError("")); +} + +TEST(StatusOrDeathTest, TestPointerDefaultCtorValue) { + absl::StatusOr thing; + EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError("")); +} + +TEST(StatusOrDeathTest, TestPointerValueNotOk) { + absl::StatusOr thing(absl::CancelledError()); + EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError()); +} + +TEST(StatusOrDeathTest, TestPointerValueNotOkConst) { + const absl::StatusOr thing(absl::CancelledError()); + EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError()); +} + +#if GTEST_HAS_DEATH_TEST +TEST(StatusOrDeathTest, TestStatusCtorStatusOk) { + EXPECT_DEBUG_DEATH( + { + // This will DCHECK + absl::StatusOr thing(absl::OkStatus()); + // In optimized mode, we are actually going to get error::INTERNAL for + // status here, rather than crashing, so check that. + EXPECT_FALSE(thing.ok()); + EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal); + }, + "An OK status is not a valid constructor argument"); +} + +TEST(StatusOrDeathTest, TestPointerStatusCtorStatusOk) { + EXPECT_DEBUG_DEATH( + { + absl::StatusOr thing(absl::OkStatus()); + // In optimized mode, we are actually going to get error::INTERNAL for + // status here, rather than crashing, so check that. + EXPECT_FALSE(thing.ok()); + EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal); + }, + "An OK status is not a valid constructor argument"); +} +#endif + +TEST(StatusOr, ValueAccessor) { + const int kIntValue = 110; + { + absl::StatusOr status_or(kIntValue); + EXPECT_EQ(kIntValue, status_or.value()); + EXPECT_EQ(kIntValue, std::move(status_or).value()); + } + { + absl::StatusOr status_or(kIntValue); + EXPECT_THAT(status_or, + IsOkAndHolds(CopyDetectorHas(kIntValue, false, false))); + CopyDetector copy_detector = status_or.value(); + EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, false, true)); + copy_detector = std::move(status_or).value(); + EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, true, false)); + } +} + +TEST(StatusOr, BadValueAccess) { + const absl::Status kError = absl::CancelledError("message"); + absl::StatusOr status_or(kError); + EXPECT_DEATH_OR_THROW(status_or.value(), kError); +} + +TEST(StatusOr, TestStatusCtor) { + absl::StatusOr thing(absl::CancelledError()); + EXPECT_FALSE(thing.ok()); + EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled); +} + + + +TEST(StatusOr, TestValueCtor) { + const int kI = 4; + const absl::StatusOr thing(kI); + EXPECT_TRUE(thing.ok()); + EXPECT_EQ(kI, *thing); +} + +struct Foo { + const int x; + explicit Foo(int y) : x(y) {} +}; + +TEST(StatusOr, InPlaceConstruction) { + EXPECT_THAT(absl::StatusOr(absl::in_place, 10), + IsOkAndHolds(Field(&Foo::x, 10))); +} + +struct InPlaceHelper { + InPlaceHelper(std::initializer_list xs, std::unique_ptr yy) + : x(xs), y(std::move(yy)) {} + const std::vector x; + std::unique_ptr y; +}; + +TEST(StatusOr, InPlaceInitListConstruction) { + absl::StatusOr status_or(absl::in_place, {10, 11, 12}, + absl::make_unique(13)); + EXPECT_THAT(status_or, IsOkAndHolds(AllOf( + Field(&InPlaceHelper::x, ElementsAre(10, 11, 12)), + Field(&InPlaceHelper::y, Pointee(13))))); +} + +TEST(StatusOr, Emplace) { + absl::StatusOr status_or_foo(10); + status_or_foo.emplace(20); + EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20))); + status_or_foo = absl::InvalidArgumentError("msg"); + EXPECT_FALSE(status_or_foo.ok()); + EXPECT_EQ(status_or_foo.status().code(), absl::StatusCode::kInvalidArgument); + EXPECT_EQ(status_or_foo.status().message(), "msg"); + status_or_foo.emplace(20); + EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20))); +} + +TEST(StatusOr, EmplaceInitializerList) { + absl::StatusOr status_or(absl::in_place, {10, 11, 12}, + absl::make_unique(13)); + status_or.emplace({1, 2, 3}, absl::make_unique(4)); + EXPECT_THAT(status_or, + IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)), + Field(&InPlaceHelper::y, Pointee(4))))); + status_or = absl::InvalidArgumentError("msg"); + EXPECT_FALSE(status_or.ok()); + EXPECT_EQ(status_or.status().code(), absl::StatusCode::kInvalidArgument); + EXPECT_EQ(status_or.status().message(), "msg"); + status_or.emplace({1, 2, 3}, absl::make_unique(4)); + EXPECT_THAT(status_or, + IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)), + Field(&InPlaceHelper::y, Pointee(4))))); +} + +TEST(StatusOr, TestCopyCtorStatusOk) { + const int kI = 4; + const absl::StatusOr original(kI); + const absl::StatusOr copy(original); + EXPECT_OK(copy.status()); + EXPECT_EQ(*original, *copy); +} + +TEST(StatusOr, TestCopyCtorStatusNotOk) { + absl::StatusOr original(absl::CancelledError()); + absl::StatusOr copy(original); + EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled); +} + +TEST(StatusOr, TestCopyCtorNonAssignable) { + const int kI = 4; + CopyNoAssign value(kI); + absl::StatusOr original(value); + absl::StatusOr copy(original); + EXPECT_OK(copy.status()); + EXPECT_EQ(original->foo, copy->foo); +} + +TEST(StatusOr, TestCopyCtorStatusOKConverting) { + const int kI = 4; + absl::StatusOr original(kI); + absl::StatusOr copy(original); + EXPECT_OK(copy.status()); + EXPECT_DOUBLE_EQ(*original, *copy); +} + +TEST(StatusOr, TestCopyCtorStatusNotOkConverting) { + absl::StatusOr original(absl::CancelledError()); + absl::StatusOr copy(original); + EXPECT_EQ(copy.status(), original.status()); +} + +TEST(StatusOr, TestAssignmentStatusOk) { + // Copy assignmment + { + const auto p = std::make_shared(17); + absl::StatusOr> source(p); + + absl::StatusOr> target; + target = source; + + ASSERT_TRUE(target.ok()); + EXPECT_OK(target.status()); + EXPECT_EQ(p, *target); + + ASSERT_TRUE(source.ok()); + EXPECT_OK(source.status()); + EXPECT_EQ(p, *source); + } + + // Move asssignment + { + const auto p = std::make_shared(17); + absl::StatusOr> source(p); + + absl::StatusOr> target; + target = std::move(source); + + ASSERT_TRUE(target.ok()); + EXPECT_OK(target.status()); + EXPECT_EQ(p, *target); + + ASSERT_TRUE(source.ok()); + EXPECT_OK(source.status()); + EXPECT_EQ(nullptr, *source); + } +} + +TEST(StatusOr, TestAssignmentStatusNotOk) { + // Copy assignment + { + const absl::Status expected = absl::CancelledError(); + absl::StatusOr source(expected); + + absl::StatusOr target; + target = source; + + EXPECT_FALSE(target.ok()); + EXPECT_EQ(expected, target.status()); + + EXPECT_FALSE(source.ok()); + EXPECT_EQ(expected, source.status()); + } + + // Move assignment + { + const absl::Status expected = absl::CancelledError(); + absl::StatusOr source(expected); + + absl::StatusOr target; + target = std::move(source); + + EXPECT_FALSE(target.ok()); + EXPECT_EQ(expected, target.status()); + + EXPECT_FALSE(source.ok()); + EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal); + } +} + +TEST(StatusOr, TestAssignmentStatusOKConverting) { + // Copy assignment + { + const int kI = 4; + absl::StatusOr source(kI); + + absl::StatusOr target; + target = source; + + ASSERT_TRUE(target.ok()); + EXPECT_OK(target.status()); + EXPECT_DOUBLE_EQ(kI, *target); + + ASSERT_TRUE(source.ok()); + EXPECT_OK(source.status()); + EXPECT_DOUBLE_EQ(kI, *source); + } + + // Move assignment + { + const auto p = new int(17); + absl::StatusOr> source(absl::WrapUnique(p)); + + absl::StatusOr> target; + target = std::move(source); + + ASSERT_TRUE(target.ok()); + EXPECT_OK(target.status()); + EXPECT_EQ(p, target->get()); + + ASSERT_TRUE(source.ok()); + EXPECT_OK(source.status()); + EXPECT_EQ(nullptr, source->get()); + } +} + +struct A { + int x; +}; + +struct ImplicitConstructibleFromA { + int x; + bool moved; + ImplicitConstructibleFromA(const A& a) // NOLINT + : x(a.x), moved(false) {} + ImplicitConstructibleFromA(A&& a) // NOLINT + : x(a.x), moved(true) {} +}; + +TEST(StatusOr, ImplicitConvertingConstructor) { + EXPECT_THAT( + absl::implicit_cast>( + absl::StatusOr(A{11})), + IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 11), + Field(&ImplicitConstructibleFromA::moved, true)))); + absl::StatusOr a(A{12}); + EXPECT_THAT( + absl::implicit_cast>(a), + IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 12), + Field(&ImplicitConstructibleFromA::moved, false)))); +} + +struct ExplicitConstructibleFromA { + int x; + bool moved; + explicit ExplicitConstructibleFromA(const A& a) : x(a.x), moved(false) {} + explicit ExplicitConstructibleFromA(A&& a) : x(a.x), moved(true) {} +}; + +TEST(StatusOr, ExplicitConvertingConstructor) { + EXPECT_FALSE( + (std::is_convertible&, + absl::StatusOr>::value)); + EXPECT_FALSE( + (std::is_convertible&&, + absl::StatusOr>::value)); + EXPECT_THAT( + absl::StatusOr(absl::StatusOr(A{11})), + IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 11), + Field(&ExplicitConstructibleFromA::moved, true)))); + absl::StatusOr a(A{12}); + EXPECT_THAT( + absl::StatusOr(a), + IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 12), + Field(&ExplicitConstructibleFromA::moved, false)))); +} + +struct ImplicitConstructibleFromBool { + ImplicitConstructibleFromBool(bool y) : x(y) {} // NOLINT + bool x = false; +}; + +struct ConvertibleToBool { + explicit ConvertibleToBool(bool y) : x(y) {} + operator bool() const { return x; } // NOLINT + bool x = false; +}; + +TEST(StatusOr, ImplicitBooleanConstructionWithImplicitCasts) { + EXPECT_THAT(absl::StatusOr(absl::StatusOr(true)), + IsOkAndHolds(true)); + EXPECT_THAT(absl::StatusOr(absl::StatusOr(false)), + IsOkAndHolds(false)); + EXPECT_THAT( + absl::implicit_cast>( + absl::StatusOr(false)), + IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false))); + EXPECT_FALSE((std::is_convertible< + absl::StatusOr, + absl::StatusOr>::value)); +} + +TEST(StatusOr, BooleanConstructionWithImplicitCasts) { + EXPECT_THAT(absl::StatusOr(absl::StatusOr(true)), + IsOkAndHolds(true)); + EXPECT_THAT(absl::StatusOr(absl::StatusOr(false)), + IsOkAndHolds(false)); + EXPECT_THAT( + absl::StatusOr{ + absl::StatusOr(false)}, + IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false))); + EXPECT_THAT( + absl::StatusOr{ + absl::StatusOr(absl::InvalidArgumentError(""))}, + Not(IsOk())); + + EXPECT_THAT( + absl::StatusOr{ + absl::StatusOr(ConvertibleToBool{false})}, + IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false))); + EXPECT_THAT( + absl::StatusOr{ + absl::StatusOr(absl::InvalidArgumentError(""))}, + Not(IsOk())); +} + +TEST(StatusOr, ConstImplicitCast) { + EXPECT_THAT(absl::implicit_cast>( + absl::StatusOr(true)), + IsOkAndHolds(true)); + EXPECT_THAT(absl::implicit_cast>( + absl::StatusOr(false)), + IsOkAndHolds(false)); + EXPECT_THAT(absl::implicit_cast>( + absl::StatusOr(true)), + IsOkAndHolds(true)); + EXPECT_THAT(absl::implicit_cast>( + absl::StatusOr(false)), + IsOkAndHolds(false)); + EXPECT_THAT(absl::implicit_cast>( + absl::StatusOr("foo")), + IsOkAndHolds("foo")); + EXPECT_THAT(absl::implicit_cast>( + absl::StatusOr("foo")), + IsOkAndHolds("foo")); + EXPECT_THAT( + absl::implicit_cast>>( + absl::StatusOr>( + std::make_shared("foo"))), + IsOkAndHolds(Pointee(std::string("foo")))); +} + +TEST(StatusOr, ConstExplicitConstruction) { + EXPECT_THAT(absl::StatusOr(absl::StatusOr(true)), + IsOkAndHolds(true)); + EXPECT_THAT(absl::StatusOr(absl::StatusOr(false)), + IsOkAndHolds(false)); + EXPECT_THAT(absl::StatusOr(absl::StatusOr(true)), + IsOkAndHolds(true)); + EXPECT_THAT(absl::StatusOr(absl::StatusOr(false)), + IsOkAndHolds(false)); +} + +struct ExplicitConstructibleFromInt { + int x; + explicit ExplicitConstructibleFromInt(int y) : x(y) {} +}; + +TEST(StatusOr, ExplicitConstruction) { + EXPECT_THAT(absl::StatusOr(10), + IsOkAndHolds(Field(&ExplicitConstructibleFromInt::x, 10))); +} + +TEST(StatusOr, ImplicitConstruction) { + // Check implicit casting works. + auto status_or = + absl::implicit_cast>>(10); + EXPECT_THAT(status_or, IsOkAndHolds(VariantWith(10))); +} + +TEST(StatusOr, ImplicitConstructionFromInitliazerList) { + // Note: dropping the explicit std::initializer_list is not supported + // by absl::StatusOr or absl::optional. + auto status_or = + absl::implicit_cast>>({{10, 20, 30}}); + EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30))); +} + +TEST(StatusOr, UniquePtrImplicitConstruction) { + auto status_or = absl::implicit_cast>>( + absl::make_unique()); + EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr))); +} + +TEST(StatusOr, NestedStatusOrCopyAndMoveConstructorTests) { + absl::StatusOr> status_or = CopyDetector(10); + absl::StatusOr> status_error = + absl::InvalidArgumentError("foo"); + EXPECT_THAT(status_or, + IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false)))); + absl::StatusOr> a = status_or; + EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); + absl::StatusOr> a_err = status_error; + EXPECT_THAT(a_err, Not(IsOk())); + + const absl::StatusOr>& cref = status_or; + absl::StatusOr> b = cref; // NOLINT + EXPECT_THAT(b, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); + const absl::StatusOr>& cref_err = status_error; + absl::StatusOr> b_err = cref_err; // NOLINT + EXPECT_THAT(b_err, Not(IsOk())); + + absl::StatusOr> c = std::move(status_or); + EXPECT_THAT(c, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false)))); + absl::StatusOr> c_err = std::move(status_error); + EXPECT_THAT(c_err, Not(IsOk())); +} + +TEST(StatusOr, NestedStatusOrCopyAndMoveAssignment) { + absl::StatusOr> status_or = CopyDetector(10); + absl::StatusOr> status_error = + absl::InvalidArgumentError("foo"); + absl::StatusOr> a; + a = status_or; + EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); + a = status_error; + EXPECT_THAT(a, Not(IsOk())); + + const absl::StatusOr>& cref = status_or; + a = cref; + EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); + const absl::StatusOr>& cref_err = status_error; + a = cref_err; + EXPECT_THAT(a, Not(IsOk())); + a = std::move(status_or); + EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false)))); + a = std::move(status_error); + EXPECT_THAT(a, Not(IsOk())); +} + +struct Copyable { + Copyable() {} + Copyable(const Copyable&) {} + Copyable& operator=(const Copyable&) { return *this; } +}; + +struct MoveOnly { + MoveOnly() {} + MoveOnly(MoveOnly&&) {} + MoveOnly& operator=(MoveOnly&&) { return *this; } +}; + +struct NonMovable { + NonMovable() {} + NonMovable(const NonMovable&) = delete; + NonMovable(NonMovable&&) = delete; + NonMovable& operator=(const NonMovable&) = delete; + NonMovable& operator=(NonMovable&&) = delete; +}; + +TEST(StatusOr, CopyAndMoveAbility) { + EXPECT_TRUE(std::is_copy_constructible::value); + EXPECT_TRUE(std::is_copy_assignable::value); + EXPECT_TRUE(std::is_move_constructible::value); + EXPECT_TRUE(std::is_move_assignable::value); + EXPECT_FALSE(std::is_copy_constructible::value); + EXPECT_FALSE(std::is_copy_assignable::value); + EXPECT_TRUE(std::is_move_constructible::value); + EXPECT_TRUE(std::is_move_assignable::value); + EXPECT_FALSE(std::is_copy_constructible::value); + EXPECT_FALSE(std::is_copy_assignable::value); + EXPECT_FALSE(std::is_move_constructible::value); + EXPECT_FALSE(std::is_move_assignable::value); +} + +TEST(StatusOr, StatusOrAnyCopyAndMoveConstructorTests) { + absl::StatusOr status_or = CopyDetector(10); + absl::StatusOr status_error = absl::InvalidArgumentError("foo"); + EXPECT_THAT( + status_or, + IsOkAndHolds(AnyWith(CopyDetectorHas(10, true, false)))); + absl::StatusOr a = status_or; + EXPECT_THAT( + a, IsOkAndHolds(AnyWith(CopyDetectorHas(10, false, true)))); + absl::StatusOr a_err = status_error; + EXPECT_THAT(a_err, Not(IsOk())); + + const absl::StatusOr& cref = status_or; + // No lint for no-change copy. + absl::StatusOr b = cref; // NOLINT + EXPECT_THAT( + b, IsOkAndHolds(AnyWith(CopyDetectorHas(10, false, true)))); + const absl::StatusOr& cref_err = status_error; + // No lint for no-change copy. + absl::StatusOr b_err = cref_err; // NOLINT + EXPECT_THAT(b_err, Not(IsOk())); + + absl::StatusOr c = std::move(status_or); + EXPECT_THAT( + c, IsOkAndHolds(AnyWith(CopyDetectorHas(10, true, false)))); + absl::StatusOr c_err = std::move(status_error); + EXPECT_THAT(c_err, Not(IsOk())); +} + +TEST(StatusOr, StatusOrAnyCopyAndMoveAssignment) { + absl::StatusOr status_or = CopyDetector(10); + absl::StatusOr status_error = absl::InvalidArgumentError("foo"); + absl::StatusOr a; + a = status_or; + EXPECT_THAT( + a, IsOkAndHolds(AnyWith(CopyDetectorHas(10, false, true)))); + a = status_error; + EXPECT_THAT(a, Not(IsOk())); + + const absl::StatusOr& cref = status_or; + a = cref; + EXPECT_THAT( + a, IsOkAndHolds(AnyWith(CopyDetectorHas(10, false, true)))); + const absl::StatusOr& cref_err = status_error; + a = cref_err; + EXPECT_THAT(a, Not(IsOk())); + a = std::move(status_or); + EXPECT_THAT( + a, IsOkAndHolds(AnyWith(CopyDetectorHas(10, true, false)))); + a = std::move(status_error); + EXPECT_THAT(a, Not(IsOk())); +} + +TEST(StatusOr, StatusOrCopyAndMoveTestsConstructor) { + absl::StatusOr status_or(10); + ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false))); + absl::StatusOr a(status_or); + EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true))); + const absl::StatusOr& cref = status_or; + absl::StatusOr b(cref); // NOLINT + EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true))); + absl::StatusOr c(std::move(status_or)); + EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false))); +} + +TEST(StatusOr, StatusOrCopyAndMoveTestsAssignment) { + absl::StatusOr status_or(10); + ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false))); + absl::StatusOr a; + a = status_or; + EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true))); + const absl::StatusOr& cref = status_or; + absl::StatusOr b; + b = cref; + EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true))); + absl::StatusOr c; + c = std::move(status_or); + EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false))); +} + +TEST(StatusOr, AbslAnyAssignment) { + EXPECT_FALSE((std::is_assignable, + absl::StatusOr>::value)); + absl::StatusOr status_or; + status_or = absl::InvalidArgumentError("foo"); + EXPECT_THAT(status_or, Not(IsOk())); +} + +TEST(StatusOr, ImplicitAssignment) { + absl::StatusOr> status_or; + status_or = 10; + EXPECT_THAT(status_or, IsOkAndHolds(VariantWith(10))); +} + +TEST(StatusOr, SelfDirectInitAssignment) { + absl::StatusOr> status_or = {{10, 20, 30}}; + status_or = *status_or; + EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30))); +} + +TEST(StatusOr, ImplicitCastFromInitializerList) { + absl::StatusOr> status_or = {{10, 20, 30}}; + EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30))); +} + +TEST(StatusOr, UniquePtrImplicitAssignment) { + absl::StatusOr> status_or; + status_or = absl::make_unique(); + EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr))); +} + +TEST(StatusOr, Pointer) { + struct A {}; + struct B : public A {}; + struct C : private A {}; + + EXPECT_TRUE((std::is_constructible, B*>::value)); + EXPECT_TRUE((std::is_convertible>::value)); + EXPECT_FALSE((std::is_constructible, C*>::value)); + EXPECT_FALSE((std::is_convertible>::value)); +} + +TEST(StatusOr, TestAssignmentStatusNotOkConverting) { + // Copy assignment + { + const absl::Status expected = absl::CancelledError(); + absl::StatusOr source(expected); + + absl::StatusOr target; + target = source; + + EXPECT_FALSE(target.ok()); + EXPECT_EQ(expected, target.status()); + + EXPECT_FALSE(source.ok()); + EXPECT_EQ(expected, source.status()); + } + + // Move assignment + { + const absl::Status expected = absl::CancelledError(); + absl::StatusOr source(expected); + + absl::StatusOr target; + target = std::move(source); + + EXPECT_FALSE(target.ok()); + EXPECT_EQ(expected, target.status()); + + EXPECT_FALSE(source.ok()); + EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal); + } +} + +TEST(StatusOr, SelfAssignment) { + // Copy-assignment, status OK + { + // A string long enough that it's likely to defeat any inline representation + // optimization. + const std::string long_str(128, 'a'); + + absl::StatusOr so = long_str; + so = *&so; + + ASSERT_TRUE(so.ok()); + EXPECT_OK(so.status()); + EXPECT_EQ(long_str, *so); + } + + // Copy-assignment, error status + { + absl::StatusOr so = absl::NotFoundError("taco"); + so = *&so; + + EXPECT_FALSE(so.ok()); + EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound); + EXPECT_EQ(so.status().message(), "taco"); + } + + // Move-assignment with copyable type, status OK + { + absl::StatusOr so = 17; + + // Fool the compiler, which otherwise complains. + auto& same = so; + so = std::move(same); + + ASSERT_TRUE(so.ok()); + EXPECT_OK(so.status()); + EXPECT_EQ(17, *so); + } + + // Move-assignment with copyable type, error status + { + absl::StatusOr so = absl::NotFoundError("taco"); + + // Fool the compiler, which otherwise complains. + auto& same = so; + so = std::move(same); + + EXPECT_FALSE(so.ok()); + EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound); + EXPECT_EQ(so.status().message(), "taco"); + } + + // Move-assignment with non-copyable type, status OK + { + const auto raw = new int(17); + absl::StatusOr> so = absl::WrapUnique(raw); + + // Fool the compiler, which otherwise complains. + auto& same = so; + so = std::move(same); + + ASSERT_TRUE(so.ok()); + EXPECT_OK(so.status()); + EXPECT_EQ(raw, so->get()); + } + + // Move-assignment with non-copyable type, error status + { + absl::StatusOr> so = absl::NotFoundError("taco"); + + // Fool the compiler, which otherwise complains. + auto& same = so; + so = std::move(same); + + EXPECT_FALSE(so.ok()); + EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound); + EXPECT_EQ(so.status().message(), "taco"); + } +} + +// These types form the overload sets of the constructors and the assignment +// operators of `MockValue`. They distinguish construction from assignment, +// lvalue from rvalue. +struct FromConstructibleAssignableLvalue {}; +struct FromConstructibleAssignableRvalue {}; +struct FromImplicitConstructibleOnly {}; +struct FromAssignableOnly {}; + +// This class is for testing the forwarding value assignments of `StatusOr`. +// `from_rvalue` indicates whether the constructor or the assignment taking +// rvalue reference is called. `from_assignment` indicates whether any +// assignment is called. +struct MockValue { + // Constructs `MockValue` from `FromConstructibleAssignableLvalue`. + MockValue(const FromConstructibleAssignableLvalue&) // NOLINT + : from_rvalue(false), assigned(false) {} + // Constructs `MockValue` from `FromConstructibleAssignableRvalue`. + MockValue(FromConstructibleAssignableRvalue&&) // NOLINT + : from_rvalue(true), assigned(false) {} + // Constructs `MockValue` from `FromImplicitConstructibleOnly`. + // `MockValue` is not assignable from `FromImplicitConstructibleOnly`. + MockValue(const FromImplicitConstructibleOnly&) // NOLINT + : from_rvalue(false), assigned(false) {} + // Assigns `FromConstructibleAssignableLvalue`. + MockValue& operator=(const FromConstructibleAssignableLvalue&) { + from_rvalue = false; + assigned = true; + return *this; + } + // Assigns `FromConstructibleAssignableRvalue` (rvalue only). + MockValue& operator=(FromConstructibleAssignableRvalue&&) { + from_rvalue = true; + assigned = true; + return *this; + } + // Assigns `FromAssignableOnly`, but not constructible from + // `FromAssignableOnly`. + MockValue& operator=(const FromAssignableOnly&) { + from_rvalue = false; + assigned = true; + return *this; + } + bool from_rvalue; + bool assigned; +}; + +// operator=(U&&) +TEST(StatusOr, PerfectForwardingAssignment) { + // U == T + constexpr int kValue1 = 10, kValue2 = 20; + absl::StatusOr status_or; + CopyDetector lvalue(kValue1); + status_or = lvalue; + EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue1, false, true))); + status_or = CopyDetector(kValue2); + EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue2, true, false))); + + // U != T + EXPECT_TRUE( + (std::is_assignable&, + const FromConstructibleAssignableLvalue&>::value)); + EXPECT_TRUE((std::is_assignable&, + FromConstructibleAssignableLvalue&&>::value)); + EXPECT_FALSE( + (std::is_assignable&, + const FromConstructibleAssignableRvalue&>::value)); + EXPECT_TRUE((std::is_assignable&, + FromConstructibleAssignableRvalue&&>::value)); + EXPECT_TRUE( + (std::is_assignable&, + const FromImplicitConstructibleOnly&>::value)); + EXPECT_FALSE((std::is_assignable&, + const FromAssignableOnly&>::value)); + + absl::StatusOr from_lvalue(FromConstructibleAssignableLvalue{}); + EXPECT_FALSE(from_lvalue->from_rvalue); + EXPECT_FALSE(from_lvalue->assigned); + from_lvalue = FromConstructibleAssignableLvalue{}; + EXPECT_FALSE(from_lvalue->from_rvalue); + EXPECT_TRUE(from_lvalue->assigned); + + absl::StatusOr from_rvalue(FromConstructibleAssignableRvalue{}); + EXPECT_TRUE(from_rvalue->from_rvalue); + EXPECT_FALSE(from_rvalue->assigned); + from_rvalue = FromConstructibleAssignableRvalue{}; + EXPECT_TRUE(from_rvalue->from_rvalue); + EXPECT_TRUE(from_rvalue->assigned); + + absl::StatusOr from_implicit_constructible( + FromImplicitConstructibleOnly{}); + EXPECT_FALSE(from_implicit_constructible->from_rvalue); + EXPECT_FALSE(from_implicit_constructible->assigned); + // construct a temporary `StatusOr` object and invoke the `StatusOr` move + // assignment operator. + from_implicit_constructible = FromImplicitConstructibleOnly{}; + EXPECT_FALSE(from_implicit_constructible->from_rvalue); + EXPECT_FALSE(from_implicit_constructible->assigned); +} + +TEST(StatusOr, TestStatus) { + absl::StatusOr good(4); + EXPECT_TRUE(good.ok()); + absl::StatusOr bad(absl::CancelledError()); + EXPECT_FALSE(bad.ok()); + EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled); +} + +TEST(StatusOr, OperatorStarRefQualifiers) { + static_assert( + std::is_same&>())>(), + "Unexpected ref-qualifiers"); + static_assert( + std::is_same&>())>(), + "Unexpected ref-qualifiers"); + static_assert( + std::is_same&&>())>(), + "Unexpected ref-qualifiers"); + static_assert( + std::is_same&&>())>(), + "Unexpected ref-qualifiers"); +} + +TEST(StatusOr, OperatorStar) { + const absl::StatusOr const_lvalue("hello"); + EXPECT_EQ("hello", *const_lvalue); + + absl::StatusOr lvalue("hello"); + EXPECT_EQ("hello", *lvalue); + + // Note: Recall that std::move() is equivalent to a static_cast to an rvalue + // reference type. + const absl::StatusOr const_rvalue("hello"); + EXPECT_EQ("hello", *std::move(const_rvalue)); // NOLINT + + absl::StatusOr rvalue("hello"); + EXPECT_EQ("hello", *std::move(rvalue)); +} + +TEST(StatusOr, OperatorArrowQualifiers) { + static_assert( + std::is_same< + const int*, + decltype(std::declval&>().operator->())>(), + "Unexpected qualifiers"); + static_assert( + std::is_same< + int*, decltype(std::declval&>().operator->())>(), + "Unexpected qualifiers"); + static_assert( + std::is_same< + const int*, + decltype(std::declval&&>().operator->())>(), + "Unexpected qualifiers"); + static_assert( + std::is_same< + int*, decltype(std::declval&&>().operator->())>(), + "Unexpected qualifiers"); +} + +TEST(StatusOr, OperatorArrow) { + const absl::StatusOr const_lvalue("hello"); + EXPECT_EQ(std::string("hello"), const_lvalue->c_str()); + + absl::StatusOr lvalue("hello"); + EXPECT_EQ(std::string("hello"), lvalue->c_str()); +} + +TEST(StatusOr, RValueStatus) { + absl::StatusOr so(absl::NotFoundError("taco")); + const absl::Status s = std::move(so).status(); + + EXPECT_EQ(s.code(), absl::StatusCode::kNotFound); + EXPECT_EQ(s.message(), "taco"); + + // Check that !ok() still implies !status().ok(), even after moving out of the + // object. See the note on the rvalue ref-qualified status method. + EXPECT_FALSE(so.ok()); // NOLINT + EXPECT_FALSE(so.status().ok()); + EXPECT_EQ(so.status().code(), absl::StatusCode::kInternal); + EXPECT_EQ(so.status().message(), "Status accessed after move."); +} + +TEST(StatusOr, TestValue) { + const int kI = 4; + absl::StatusOr thing(kI); + EXPECT_EQ(kI, *thing); +} + +TEST(StatusOr, TestValueConst) { + const int kI = 4; + const absl::StatusOr thing(kI); + EXPECT_EQ(kI, *thing); +} + +TEST(StatusOr, TestPointerDefaultCtor) { + absl::StatusOr thing; + EXPECT_FALSE(thing.ok()); + EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown); +} + + + +TEST(StatusOr, TestPointerStatusCtor) { + absl::StatusOr thing(absl::CancelledError()); + EXPECT_FALSE(thing.ok()); + EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled); +} + +TEST(StatusOr, TestPointerValueCtor) { + const int kI = 4; + + // Construction from a non-null pointer + { + absl::StatusOr so(&kI); + EXPECT_TRUE(so.ok()); + EXPECT_OK(so.status()); + EXPECT_EQ(&kI, *so); + } + + // Construction from a null pointer constant + { + absl::StatusOr so(nullptr); + EXPECT_TRUE(so.ok()); + EXPECT_OK(so.status()); + EXPECT_EQ(nullptr, *so); + } + + // Construction from a non-literal null pointer + { + const int* const p = nullptr; + + absl::StatusOr so(p); + EXPECT_TRUE(so.ok()); + EXPECT_OK(so.status()); + EXPECT_EQ(nullptr, *so); + } +} + +TEST(StatusOr, TestPointerCopyCtorStatusOk) { + const int kI = 0; + absl::StatusOr original(&kI); + absl::StatusOr copy(original); + EXPECT_OK(copy.status()); + EXPECT_EQ(*original, *copy); +} + +TEST(StatusOr, TestPointerCopyCtorStatusNotOk) { + absl::StatusOr original(absl::CancelledError()); + absl::StatusOr copy(original); + EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled); +} + +TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) { + Derived derived; + absl::StatusOr original(&derived); + absl::StatusOr copy(original); + EXPECT_OK(copy.status()); + EXPECT_EQ(static_cast(*original), *copy); +} + +TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) { + absl::StatusOr original(absl::CancelledError()); + absl::StatusOr copy(original); + EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled); +} + +TEST(StatusOr, TestPointerAssignmentStatusOk) { + const int kI = 0; + absl::StatusOr source(&kI); + absl::StatusOr target; + target = source; + EXPECT_OK(target.status()); + EXPECT_EQ(*source, *target); +} + +TEST(StatusOr, TestPointerAssignmentStatusNotOk) { + absl::StatusOr source(absl::CancelledError()); + absl::StatusOr target; + target = source; + EXPECT_EQ(target.status().code(), absl::StatusCode::kCancelled); +} + +TEST(StatusOr, TestPointerAssignmentStatusOKConverting) { + Derived derived; + absl::StatusOr source(&derived); + absl::StatusOr target; + target = source; + EXPECT_OK(target.status()); + EXPECT_EQ(static_cast(*source), *target); +} + +TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) { + absl::StatusOr source(absl::CancelledError()); + absl::StatusOr target; + target = source; + EXPECT_EQ(target.status(), source.status()); +} + +TEST(StatusOr, TestPointerStatus) { + const int kI = 0; + absl::StatusOr good(&kI); + EXPECT_TRUE(good.ok()); + absl::StatusOr bad(absl::CancelledError()); + EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled); +} + +TEST(StatusOr, TestPointerValue) { + const int kI = 0; + absl::StatusOr thing(&kI); + EXPECT_EQ(&kI, *thing); +} + +TEST(StatusOr, TestPointerValueConst) { + const int kI = 0; + const absl::StatusOr thing(&kI); + EXPECT_EQ(&kI, *thing); +} + +TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) { + using EvilType = std::vector>; + static_assert(std::is_copy_constructible::value, ""); + std::vector<::absl::StatusOr> v(5); + v.reserve(v.capacity() + 10); + v.resize(v.capacity() + 10); +} + +TEST(StatusOr, ConstPayload) { + // A reduced version of a problematic type found in the wild. All of the + // operations below should compile. + absl::StatusOr a; + + // Copy-construction + absl::StatusOr b(a); + + // Copy-assignment + EXPECT_FALSE(std::is_copy_assignable>::value); + + // Move-construction + absl::StatusOr c(std::move(a)); + + // Move-assignment + EXPECT_FALSE(std::is_move_assignable>::value); +} + +TEST(StatusOr, MapToStatusOrUniquePtr) { + // A reduced version of a problematic type found in the wild. All of the + // operations below should compile. + using MapType = std::map>>; + + MapType a; + + // Move-construction + MapType b(std::move(a)); + + // Move-assignment + a = std::move(b); +} + +TEST(StatusOr, ValueOrOk) { + const absl::StatusOr status_or = 0; + EXPECT_EQ(status_or.value_or(-1), 0); +} + +TEST(StatusOr, ValueOrDefault) { + const absl::StatusOr status_or = absl::CancelledError(); + EXPECT_EQ(status_or.value_or(-1), -1); +} + +TEST(StatusOr, MoveOnlyValueOrOk) { + EXPECT_THAT(absl::StatusOr>(absl::make_unique(0)) + .value_or(absl::make_unique(-1)), + Pointee(0)); +} + +TEST(StatusOr, MoveOnlyValueOrDefault) { + EXPECT_THAT(absl::StatusOr>(absl::CancelledError()) + .value_or(absl::make_unique(-1)), + Pointee(-1)); +} + +static absl::StatusOr MakeStatus() { return 100; } + +TEST(StatusOr, TestIgnoreError) { MakeStatus().IgnoreError(); } + +TEST(StatusOr, EqualityOperator) { + constexpr int kNumCases = 4; + std::array, kNumCases> group1 = { + absl::StatusOr(1), absl::StatusOr(2), + absl::StatusOr(absl::InvalidArgumentError("msg")), + absl::StatusOr(absl::InternalError("msg"))}; + std::array, kNumCases> group2 = { + absl::StatusOr(1), absl::StatusOr(2), + absl::StatusOr(absl::InvalidArgumentError("msg")), + absl::StatusOr(absl::InternalError("msg"))}; + for (int i = 0; i < kNumCases; ++i) { + for (int j = 0; j < kNumCases; ++j) { + if (i == j) { + EXPECT_TRUE(group1[i] == group2[j]); + EXPECT_FALSE(group1[i] != group2[j]); + } else { + EXPECT_FALSE(group1[i] == group2[j]); + EXPECT_TRUE(group1[i] != group2[j]); + } + } + } +} + +struct MyType { + bool operator==(const MyType&) const { return true; } +}; + +enum class ConvTraits { kNone = 0, kImplicit = 1, kExplicit = 2 }; + +// This class has conversion operator to `StatusOr` based on value of +// `conv_traits`. +template +struct StatusOrConversionBase {}; + +template +struct StatusOrConversionBase { + operator absl::StatusOr() const& { // NOLINT + return absl::InvalidArgumentError("conversion to absl::StatusOr"); + } + operator absl::StatusOr() && { // NOLINT + return absl::InvalidArgumentError("conversion to absl::StatusOr"); + } +}; + +template +struct StatusOrConversionBase { + explicit operator absl::StatusOr() const& { + return absl::InvalidArgumentError("conversion to absl::StatusOr"); + } + explicit operator absl::StatusOr() && { + return absl::InvalidArgumentError("conversion to absl::StatusOr"); + } +}; + +// This class has conversion operator to `T` based on the value of +// `conv_traits`. +template +struct ConversionBase {}; + +template +struct ConversionBase { + operator T() const& { return t; } // NOLINT + operator T() && { return std::move(t); } // NOLINT + T t; +}; + +template +struct ConversionBase { + explicit operator T() const& { return t; } + explicit operator T() && { return std::move(t); } + T t; +}; + +// This class has conversion operator to `absl::Status` based on the value of +// `conv_traits`. +template +struct StatusConversionBase {}; + +template <> +struct StatusConversionBase { + operator absl::Status() const& { // NOLINT + return absl::InternalError("conversion to Status"); + } + operator absl::Status() && { // NOLINT + return absl::InternalError("conversion to Status"); + } +}; + +template <> +struct StatusConversionBase { + explicit operator absl::Status() const& { // NOLINT + return absl::InternalError("conversion to Status"); + } + explicit operator absl::Status() && { // NOLINT + return absl::InternalError("conversion to Status"); + } +}; + +static constexpr int kConvToStatus = 1; +static constexpr int kConvToStatusOr = 2; +static constexpr int kConvToT = 4; +static constexpr int kConvExplicit = 8; + +constexpr ConvTraits GetConvTraits(int bit, int config) { + return (config & bit) == 0 + ? ConvTraits::kNone + : ((config & kConvExplicit) == 0 ? ConvTraits::kImplicit + : ConvTraits::kExplicit); +} + +// This class conditionally has conversion operator to `absl::Status`, `T`, +// `StatusOr`, based on values of the template parameters. +template +struct CustomType + : StatusOrConversionBase, + ConversionBase, + StatusConversionBase {}; + +struct ConvertibleToAnyStatusOr { + template + operator absl::StatusOr() const { // NOLINT + return absl::InvalidArgumentError("Conversion to absl::StatusOr"); + } +}; + +// Test the rank of overload resolution for `StatusOr` constructor and +// assignment, from highest to lowest: +// 1. T/Status +// 2. U that has conversion operator to absl::StatusOr +// 3. U that is convertible to Status +// 4. U that is convertible to T +TEST(StatusOr, ConstructionFromT) { + // Construct absl::StatusOr from T when T is convertible to + // absl::StatusOr + { + ConvertibleToAnyStatusOr v; + absl::StatusOr statusor(v); + EXPECT_TRUE(statusor.ok()); + } + { + ConvertibleToAnyStatusOr v; + absl::StatusOr statusor = v; + EXPECT_TRUE(statusor.ok()); + } + // Construct absl::StatusOr from T when T is explicitly convertible to + // Status + { + CustomType v; + absl::StatusOr> statusor( + v); + EXPECT_TRUE(statusor.ok()); + } + { + CustomType v; + absl::StatusOr> statusor = + v; + EXPECT_TRUE(statusor.ok()); + } +} + +// Construct absl::StatusOr from U when U is explicitly convertible to T +TEST(StatusOr, ConstructionFromTypeConvertibleToT) { + { + CustomType v; + absl::StatusOr statusor(v); + EXPECT_TRUE(statusor.ok()); + } + { + CustomType v; + absl::StatusOr statusor = v; + EXPECT_TRUE(statusor.ok()); + } +} + +// Construct absl::StatusOr from U when U has explicit conversion operator to +// absl::StatusOr +TEST(StatusOr, ConstructionFromTypeWithConversionOperatorToStatusOrT) { + { + CustomType v; + absl::StatusOr statusor(v); + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor(v); + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor(v); + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType + v; + absl::StatusOr statusor(v); + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } +} + +TEST(StatusOr, ConstructionFromTypeConvertibleToStatus) { + // Construction fails because conversion to `Status` is explicit. + { + CustomType v; + absl::StatusOr statusor(v); + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast(v)); + } + { + CustomType v; + absl::StatusOr statusor(v); + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast(v)); + } + { + CustomType v; + absl::StatusOr statusor = v; + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast(v)); + } + { + CustomType v; + absl::StatusOr statusor = v; + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast(v)); + } +} + +TEST(StatusOr, AssignmentFromT) { + // Assign to absl::StatusOr from T when T is convertible to + // absl::StatusOr + { + ConvertibleToAnyStatusOr v; + absl::StatusOr statusor; + statusor = v; + EXPECT_TRUE(statusor.ok()); + } + // Assign to absl::StatusOr from T when T is convertible to Status + { + CustomType v; + absl::StatusOr> statusor; + statusor = v; + EXPECT_TRUE(statusor.ok()); + } +} + +TEST(StatusOr, AssignmentFromTypeConvertibleToT) { + // Assign to absl::StatusOr from U when U is convertible to T + { + CustomType v; + absl::StatusOr statusor; + statusor = v; + EXPECT_TRUE(statusor.ok()); + } +} + +TEST(StatusOr, AssignmentFromTypeWithConversionOperatortoStatusOrT) { + // Assign to absl::StatusOr from U when U has conversion operator to + // absl::StatusOr + { + CustomType v; + absl::StatusOr statusor; + statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor; + statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor; + statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } + { + CustomType v; + absl::StatusOr statusor; + statusor = v; + EXPECT_EQ(statusor, v.operator absl::StatusOr()); + } +} + +TEST(StatusOr, AssignmentFromTypeConvertibleToStatus) { + // Assign to absl::StatusOr from U when U is convertible to Status + { + CustomType v; + absl::StatusOr statusor; + statusor = v; + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast(v)); + } + { + CustomType v; + absl::StatusOr statusor; + statusor = v; + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast(v)); + } +} + +} // namespace -- cgit v1.2.3 From 2aa00ab2f22cf4e0e85e622c3254d483b2ddfb30 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 8 Feb 2021 13:20:10 -0800 Subject: Export of internal Abseil changes -- 0acc8470116819a62fd5ebbc2c64fdd703c93331 by Abseil Team : Add an attribute to HashtablezInfo which performs a bitwise XOR on all hashes. The purposes of this attribute is to identify if identical hash tables are being created. If we see a large number of identical tables, it's likely the code can be improved by using a common table as opposed to keep rebuilding the same one. PiperOrigin-RevId: 356338043 GitOrigin-RevId: 0acc8470116819a62fd5ebbc2c64fdd703c93331 Change-Id: If7d0a96629144fb41e6bef1ec93345a22df40733 --- absl/container/internal/hashtablez_sampler.cc | 2 ++ absl/container/internal/hashtablez_sampler.h | 1 + absl/container/internal/hashtablez_sampler_test.cc | 6 ++++++ 3 files changed, 9 insertions(+) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index e4484fbb..7024e54e 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -72,6 +72,7 @@ void HashtablezInfo::PrepareForSampling() { total_probe_length.store(0, std::memory_order_relaxed); hashes_bitwise_or.store(0, std::memory_order_relaxed); hashes_bitwise_and.store(~size_t{}, std::memory_order_relaxed); + hashes_bitwise_xor.store(0, std::memory_order_relaxed); create_time = absl::Now(); // The inliner makes hardcoded skip_count difficult (especially when combined @@ -235,6 +236,7 @@ void RecordInsertSlow(HashtablezInfo* info, size_t hash, info->hashes_bitwise_and.fetch_and(hash, std::memory_order_relaxed); info->hashes_bitwise_or.fetch_or(hash, std::memory_order_relaxed); + info->hashes_bitwise_xor.fetch_xor(hash, std::memory_order_relaxed); info->max_probe_length.store( std::max(info->max_probe_length.load(std::memory_order_relaxed), probe_length), diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 394348da..65d3fb5b 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -78,6 +78,7 @@ struct HashtablezInfo { std::atomic total_probe_length; std::atomic hashes_bitwise_or; std::atomic hashes_bitwise_and; + std::atomic hashes_bitwise_xor; // `HashtablezSampler` maintains intrusive linked lists for all samples. See // comments on `HashtablezSampler::all_` for details on these. `init_mu` diff --git a/absl/container/internal/hashtablez_sampler_test.cc b/absl/container/internal/hashtablez_sampler_test.cc index 8d10a1e9..5f4c83b7 100644 --- a/absl/container/internal/hashtablez_sampler_test.cc +++ b/absl/container/internal/hashtablez_sampler_test.cc @@ -89,6 +89,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) { EXPECT_EQ(info.total_probe_length.load(), 0); EXPECT_EQ(info.hashes_bitwise_or.load(), 0); EXPECT_EQ(info.hashes_bitwise_and.load(), ~size_t{}); + EXPECT_EQ(info.hashes_bitwise_xor.load(), 0); EXPECT_GE(info.create_time, test_start); info.capacity.store(1, std::memory_order_relaxed); @@ -98,6 +99,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) { info.total_probe_length.store(1, std::memory_order_relaxed); info.hashes_bitwise_or.store(1, std::memory_order_relaxed); info.hashes_bitwise_and.store(1, std::memory_order_relaxed); + info.hashes_bitwise_xor.store(1, std::memory_order_relaxed); info.create_time = test_start - absl::Hours(20); info.PrepareForSampling(); @@ -109,6 +111,7 @@ TEST(HashtablezInfoTest, PrepareForSampling) { EXPECT_EQ(info.total_probe_length.load(), 0); EXPECT_EQ(info.hashes_bitwise_or.load(), 0); EXPECT_EQ(info.hashes_bitwise_and.load(), ~size_t{}); + EXPECT_EQ(info.hashes_bitwise_xor.load(), 0); EXPECT_GE(info.create_time, test_start); } @@ -133,14 +136,17 @@ TEST(HashtablezInfoTest, RecordInsert) { EXPECT_EQ(info.max_probe_length.load(), 6); EXPECT_EQ(info.hashes_bitwise_and.load(), 0x0000FF00); EXPECT_EQ(info.hashes_bitwise_or.load(), 0x0000FF00); + EXPECT_EQ(info.hashes_bitwise_xor.load(), 0x0000FF00); RecordInsertSlow(&info, 0x000FF000, 4 * kProbeLength); EXPECT_EQ(info.max_probe_length.load(), 6); EXPECT_EQ(info.hashes_bitwise_and.load(), 0x0000F000); EXPECT_EQ(info.hashes_bitwise_or.load(), 0x000FFF00); + EXPECT_EQ(info.hashes_bitwise_xor.load(), 0x000F0F00); RecordInsertSlow(&info, 0x00FF0000, 12 * kProbeLength); EXPECT_EQ(info.max_probe_length.load(), 12); EXPECT_EQ(info.hashes_bitwise_and.load(), 0x00000000); EXPECT_EQ(info.hashes_bitwise_or.load(), 0x00FFFF00); + EXPECT_EQ(info.hashes_bitwise_xor.load(), 0x00F00F00); } TEST(HashtablezInfoTest, RecordErase) { -- cgit v1.2.3 From 0b5af594fc200b77b130dd65d2412bdd8e1e2c76 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 19 Feb 2021 10:26:08 -0800 Subject: Export of internal Abseil changes -- 1a5831c2b4b85e0151b7952e47f4b80827937620 by Laramie Leavitt : Implement FuzzingBitGen, an adapter which allows existing randomized tests which use absl::BitGenRef to easily integrate with fuzz testing. I found myself implementing a similar option in our tensorstore project to fuzz test a storage layer and figured that it would be more useful as a common tool with defaults that take the non-random path. This is similar to the FuzzedDataProvider mechanism which generates random values from a fuzz string, and is used to generate fuzz test inputs, and internally it uses FuzzedDataProvider. The basic technique used here is to construct mocking lambdas for all of the absl mock distribution configurations, and forwarding the parameters to fuzzing-specific implementations that call into FuzzedDataProvider. The default paths for the distributions are either the bounds or a median value. PiperOrigin-RevId: 358432715 -- e7968538c5ef5cd0b9822dbeac0f659b5e7d49b3 by Derek Mauro : Give extern C symbols a unique name when the inline namespace is given. This partially addresses #851 PiperOrigin-RevId: 358403842 GitOrigin-RevId: 1a5831c2b4b85e0151b7952e47f4b80827937620 Change-Id: Id5ca0251498e390a8efa7210a17cc2cabb2c7dd8 --- absl/base/config.h | 6 ++++ absl/base/dynamic_annotations.h | 34 +++++++++++++++------- absl/base/internal/spinlock_akaros.inc | 4 +-- absl/base/internal/spinlock_linux.inc | 6 ++-- absl/base/internal/spinlock_posix.inc | 4 +-- absl/base/internal/spinlock_wait.h | 10 ++++--- absl/base/internal/spinlock_win32.inc | 10 +++---- absl/container/internal/hashtablez_sampler.cc | 4 ++- absl/container/internal/hashtablez_sampler.h | 2 +- .../hashtablez_sampler_force_weak_definition.cc | 3 +- absl/flags/usage_config.cc | 5 ++-- absl/flags/usage_config.h | 3 +- absl/random/internal/mock_helpers.h | 17 +++++++---- absl/synchronization/internal/per_thread_sem.cc | 4 +-- absl/synchronization/internal/per_thread_sem.h | 8 ++--- absl/synchronization/mutex.cc | 6 ++-- absl/synchronization/mutex.h | 2 +- absl/time/clock.cc | 3 +- absl/time/clock.h | 4 +-- 19 files changed, 86 insertions(+), 49 deletions(-) (limited to 'absl/container/internal/hashtablez_sampler.cc') diff --git a/absl/base/config.h b/absl/base/config.h index 444330d3..95449969 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -121,10 +121,16 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #if ABSL_OPTION_USE_INLINE_NAMESPACE == 0 #define ABSL_NAMESPACE_BEGIN #define ABSL_NAMESPACE_END +#define ABSL_INTERNAL_C_SYMBOL(x) x #elif ABSL_OPTION_USE_INLINE_NAMESPACE == 1 #define ABSL_NAMESPACE_BEGIN \ inline namespace ABSL_OPTION_INLINE_NAMESPACE_NAME { #define ABSL_NAMESPACE_END } +#define ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) x##_##v +#define ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, v) \ + ABSL_INTERNAL_C_SYMBOL_HELPER_2(x, v) +#define ABSL_INTERNAL_C_SYMBOL(x) \ + ABSL_INTERNAL_C_SYMBOL_HELPER_1(x, ABSL_OPTION_INLINE_NAMESPACE_NAME) #else #error options.h is misconfigured. #endif diff --git a/absl/base/dynamic_annotations.h b/absl/base/dynamic_annotations.h index 545f8cbc..880cbf6e 100644 --- a/absl/base/dynamic_annotations.h +++ b/absl/base/dynamic_annotations.h @@ -110,6 +110,9 @@ // Define race annotations. #if ABSL_INTERNAL_RACE_ANNOTATIONS_ENABLED == 1 +// Some of the symbols used in this section (e.g. AnnotateBenignRaceSized) are +// defined by the compiler-based santizer implementation, not by the Abseil +// library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL. // ------------------------------------------------------------- // Annotations that suppress errors. It is usually better to express the @@ -286,17 +289,22 @@ ABSL_INTERNAL_END_EXTERN_C // Define IGNORE_READS_BEGIN/_END annotations. #if ABSL_INTERNAL_READS_ANNOTATIONS_ENABLED == 1 +// Some of the symbols used in this section (e.g. AnnotateIgnoreReadsBegin) are +// defined by the compiler-based implementation, not by the Abseil +// library. Therefore they do not use ABSL_INTERNAL_C_SYMBOL. // Request the analysis tool to ignore all reads in the current thread until // ABSL_ANNOTATE_IGNORE_READS_END is called. Useful to ignore intentional racey // reads, while still checking other reads and all writes. // See also ABSL_ANNOTATE_UNPROTECTED_READ. -#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin)(__FILE__, __LINE__) +#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsBegin) \ + (__FILE__, __LINE__) // Stop ignoring reads. -#define ABSL_ANNOTATE_IGNORE_READS_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd)(__FILE__, __LINE__) +#define ABSL_ANNOTATE_IGNORE_READS_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED(AnnotateIgnoreReadsEnd) \ + (__FILE__, __LINE__) // Function prototypes of annotations provided by the compiler-based sanitizer // implementation. @@ -316,16 +324,22 @@ ABSL_INTERNAL_END_EXTERN_C // TODO(delesley) -- The exclusive lock here ignores writes as well, but // allows IGNORE_READS_AND_WRITES to work properly. -#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsBegin)() +#define ABSL_ANNOTATE_IGNORE_READS_BEGIN() \ + ABSL_INTERNAL_GLOBAL_SCOPED( \ + ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsBegin)) \ + () -#define ABSL_ANNOTATE_IGNORE_READS_END() \ - ABSL_INTERNAL_GLOBAL_SCOPED(AbslInternalAnnotateIgnoreReadsEnd)() +#define ABSL_ANNOTATE_IGNORE_READS_END() \ + ABSL_INTERNAL_GLOBAL_SCOPED( \ + ABSL_INTERNAL_C_SYMBOL(AbslInternalAnnotateIgnoreReadsEnd)) \ + () -ABSL_INTERNAL_STATIC_INLINE void AbslInternalAnnotateIgnoreReadsBegin() +ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL( + AbslInternalAnnotateIgnoreReadsBegin)() ABSL_INTERNAL_IGNORE_READS_BEGIN_ATTRIBUTE {} -ABSL_INTERNAL_STATIC_INLINE void AbslInternalAnnotateIgnoreReadsEnd() +ABSL_INTERNAL_STATIC_INLINE void ABSL_INTERNAL_C_SYMBOL( + AbslInternalAnnotateIgnoreReadsEnd)() ABSL_INTERNAL_IGNORE_READS_END_ATTRIBUTE {} #else diff --git a/absl/base/internal/spinlock_akaros.inc b/absl/base/internal/spinlock_akaros.inc index bc468940..7b0cada4 100644 --- a/absl/base/internal/spinlock_akaros.inc +++ b/absl/base/internal/spinlock_akaros.inc @@ -20,7 +20,7 @@ extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic* /* lock_word */, uint32_t /* value */, int /* loop */, absl::base_internal::SchedulingMode /* mode */) { // In Akaros, one must take care not to call anything that could cause a @@ -29,7 +29,7 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( // arbitrary code. } -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( std::atomic* /* lock_word */, bool /* all */) {} } // extern "C" diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc index e31c6ed4..202f7cdf 100644 --- a/absl/base/internal/spinlock_linux.inc +++ b/absl/base/internal/spinlock_linux.inc @@ -56,7 +56,7 @@ static_assert(sizeof(std::atomic) == sizeof(int), extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode) { absl::base_internal::ErrnoSaver errno_saver; @@ -66,8 +66,8 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm); } -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic *w, - bool all) { +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( + std::atomic *w, bool all) { syscall(SYS_futex, w, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, 0); } diff --git a/absl/base/internal/spinlock_posix.inc b/absl/base/internal/spinlock_posix.inc index fcd21b15..4f6f887d 100644 --- a/absl/base/internal/spinlock_posix.inc +++ b/absl/base/internal/spinlock_posix.inc @@ -25,7 +25,7 @@ extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic* /* lock_word */, uint32_t /* value */, int loop, absl::base_internal::SchedulingMode /* mode */) { absl::base_internal::ErrnoSaver errno_saver; @@ -40,7 +40,7 @@ ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( } } -ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( std::atomic* /* lock_word */, bool /* all */) {} } // extern "C" diff --git a/absl/base/internal/spinlock_wait.h b/absl/base/internal/spinlock_wait.h index c34ce41c..579bd09f 100644 --- a/absl/base/internal/spinlock_wait.h +++ b/absl/base/internal/spinlock_wait.h @@ -71,21 +71,23 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalSpinLockWake(std::atomic *w, bool all); -void AbslInternalSpinLockDelay( +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(std::atomic *w, + bool all); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode scheduling_mode); } inline void absl::base_internal::SpinLockWake(std::atomic *w, bool all) { - AbslInternalSpinLockWake(w, all); + ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(w, all); } inline void absl::base_internal::SpinLockDelay( std::atomic *w, uint32_t value, int loop, absl::base_internal::SchedulingMode scheduling_mode) { - AbslInternalSpinLockDelay(w, value, loop, scheduling_mode); + ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay) + (w, value, loop, scheduling_mode); } #endif // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ diff --git a/absl/base/internal/spinlock_win32.inc b/absl/base/internal/spinlock_win32.inc index 78654b5b..9d224813 100644 --- a/absl/base/internal/spinlock_win32.inc +++ b/absl/base/internal/spinlock_win32.inc @@ -20,9 +20,9 @@ extern "C" { -void AbslInternalSpinLockDelay(std::atomic* /* lock_word */, - uint32_t /* value */, int loop, - absl::base_internal::SchedulingMode /* mode */) { +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)( + std::atomic* /* lock_word */, uint32_t /* value */, int loop, + absl::base_internal::SchedulingMode /* mode */) { if (loop == 0) { } else if (loop == 1) { Sleep(0); @@ -31,7 +31,7 @@ void AbslInternalSpinLockDelay(std::atomic* /* lock_word */, } } -void AbslInternalSpinLockWake(std::atomic* /* lock_word */, - bool /* all */) {} +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)( + std::atomic* /* lock_word */, bool /* all */) {} } // extern "C" diff --git a/absl/container/internal/hashtablez_sampler.cc b/absl/container/internal/hashtablez_sampler.cc index 7024e54e..5a29bed7 100644 --- a/absl/container/internal/hashtablez_sampler.cc +++ b/absl/container/internal/hashtablez_sampler.cc @@ -181,7 +181,9 @@ static bool ShouldForceSampling() { if (ABSL_PREDICT_TRUE(state == kDontForce)) return false; if (state == kUninitialized) { - state = AbslContainerInternalSampleEverything() ? kForce : kDontForce; + state = ABSL_INTERNAL_C_SYMBOL(AbslContainerInternalSampleEverything)() + ? kForce + : kDontForce; global_state.store(state, std::memory_order_relaxed); } return state == kForce; diff --git a/absl/container/internal/hashtablez_sampler.h b/absl/container/internal/hashtablez_sampler.h index 65d3fb5b..85685f72 100644 --- a/absl/container/internal/hashtablez_sampler.h +++ b/absl/container/internal/hashtablez_sampler.h @@ -313,7 +313,7 @@ void SetHashtablezMaxSamples(int32_t max); // initialization of static storage duration objects. // The definition of this constant is weak, which allows us to inject a // different value for it at link time. -extern "C" bool AbslContainerInternalSampleEverything(); +extern "C" bool ABSL_INTERNAL_C_SYMBOL(AbslContainerInternalSampleEverything)(); } // namespace container_internal ABSL_NAMESPACE_END diff --git a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc index 78b9d362..ed35a7ee 100644 --- a/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +++ b/absl/container/internal/hashtablez_sampler_force_weak_definition.cc @@ -21,7 +21,8 @@ ABSL_NAMESPACE_BEGIN namespace container_internal { // See hashtablez_sampler.h for details. -extern "C" ABSL_ATTRIBUTE_WEAK bool AbslContainerInternalSampleEverything() { +extern "C" ABSL_ATTRIBUTE_WEAK bool ABSL_INTERNAL_C_SYMBOL( + AbslContainerInternalSampleEverything)() { return false; } diff --git a/absl/flags/usage_config.cc b/absl/flags/usage_config.cc index ae2f548a..5d7426db 100644 --- a/absl/flags/usage_config.cc +++ b/absl/flags/usage_config.cc @@ -34,7 +34,8 @@ extern "C" { // Additional report of fatal usage error message before we std::exit. Error is // fatal if is_fatal argument to ReportUsageError is true. -ABSL_ATTRIBUTE_WEAK void AbslInternalReportFatalUsageError(absl::string_view) {} +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL( + AbslInternalReportFatalUsageError)(absl::string_view) {} } // extern "C" @@ -128,7 +129,7 @@ void ReportUsageError(absl::string_view msg, bool is_fatal) { std::cerr << "ERROR: " << msg << std::endl; if (is_fatal) { - AbslInternalReportFatalUsageError(msg); + ABSL_INTERNAL_C_SYMBOL(AbslInternalReportFatalUsageError)(msg); } } diff --git a/absl/flags/usage_config.h b/absl/flags/usage_config.h index 96eecea2..ded70300 100644 --- a/absl/flags/usage_config.h +++ b/absl/flags/usage_config.h @@ -127,7 +127,8 @@ extern "C" { // Additional report of fatal usage error message before we std::exit. Error is // fatal if is_fatal argument to ReportUsageError is true. -void AbslInternalReportFatalUsageError(absl::string_view); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalReportFatalUsageError)( + absl::string_view); } // extern "C" diff --git a/absl/random/internal/mock_helpers.h b/absl/random/internal/mock_helpers.h index 9af27ab3..a412ff2f 100644 --- a/absl/random/internal/mock_helpers.h +++ b/absl/random/internal/mock_helpers.h @@ -80,6 +80,13 @@ class MockHelpers { } public: + // InvokeMock is private; this provides access for some specialized use cases. + template + static inline bool PrivateInvokeMock(URBG* urbg, IdType type, + void* args_tuple, void* result) { + return urbg->InvokeMock(type, args_tuple, result); + } + // Invoke a mock for the KeyT (may or may not be a signature). // // KeyT is used to generate a typeid-based lookup key for the mock. @@ -109,11 +116,11 @@ class MockHelpers { // The mocked function signature will be composed from KeyT as: // result_type(args...) template - static auto MockFor(MockURBG& m) -> decltype( - std::declval() - .template RegisterMock::result_type, - typename KeySignature::arg_tuple_type>( - std::declval())) { + static auto MockFor(MockURBG& m) + -> decltype(m.template RegisterMock< + typename KeySignature::result_type, + typename KeySignature::arg_tuple_type>( + std::declval())) { return m.template RegisterMock::result_type, typename KeySignature::arg_tuple_type>( ::absl::base_internal::FastTypeId()); diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc index 821ca9b4..a6031787 100644 --- a/absl/synchronization/internal/per_thread_sem.cc +++ b/absl/synchronization/internal/per_thread_sem.cc @@ -68,12 +68,12 @@ ABSL_NAMESPACE_END extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalPerThreadSemPost( +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)( absl::base_internal::ThreadIdentity *identity) { absl::synchronization_internal::Waiter::GetWaiter(identity)->Post(); } -ABSL_ATTRIBUTE_WEAK bool AbslInternalPerThreadSemWait( +ABSL_ATTRIBUTE_WEAK bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)( absl::synchronization_internal::KernelTimeout t) { bool timeout = false; absl::base_internal::ThreadIdentity *identity; diff --git a/absl/synchronization/internal/per_thread_sem.h b/absl/synchronization/internal/per_thread_sem.h index 2228b6e8..7beae8ef 100644 --- a/absl/synchronization/internal/per_thread_sem.h +++ b/absl/synchronization/internal/per_thread_sem.h @@ -96,20 +96,20 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalPerThreadSemPost( +void ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)( absl::base_internal::ThreadIdentity* identity); -bool AbslInternalPerThreadSemWait( +bool ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)( absl::synchronization_internal::KernelTimeout t); } // extern "C" void absl::synchronization_internal::PerThreadSem::Post( absl::base_internal::ThreadIdentity* identity) { - AbslInternalPerThreadSemPost(identity); + ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemPost)(identity); } bool absl::synchronization_internal::PerThreadSem::Wait( absl::synchronization_internal::KernelTimeout t) { - return AbslInternalPerThreadSemWait(t); + return ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(t); } #endif // ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_ diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 7e66a7d0..30264a3c 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -70,7 +70,9 @@ using absl::synchronization_internal::KernelTimeout; using absl::synchronization_internal::PerThreadSem; extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalMutexYield() { std::this_thread::yield(); } +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)() { + std::this_thread::yield(); +} } // extern "C" namespace absl { @@ -170,7 +172,7 @@ int MutexDelay(int32_t c, int mode) { ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0); if (c == limit) { // Yield once. - AbslInternalMutexYield(); + ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)(); c++; } else { // Then wait. diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 8c6d573d..73c5bf50 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -1078,7 +1078,7 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalMutexYield(); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)(); } // extern "C" #endif // ABSL_SYNCHRONIZATION_MUTEX_H_ diff --git a/absl/time/clock.cc b/absl/time/clock.cc index c61dcc03..7b204c4e 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -573,7 +573,8 @@ ABSL_NAMESPACE_END extern "C" { -ABSL_ATTRIBUTE_WEAK void AbslInternalSleepFor(absl::Duration duration) { +ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)( + absl::Duration duration) { while (duration > absl::ZeroDuration()) { absl::Duration to_sleep = std::min(duration, absl::MaxSleep()); absl::SleepOnce(to_sleep); diff --git a/absl/time/clock.h b/absl/time/clock.h index 27764a92..5fe244d6 100644 --- a/absl/time/clock.h +++ b/absl/time/clock.h @@ -64,11 +64,11 @@ ABSL_NAMESPACE_END // By changing our extension points to be extern "C", we dodge this // check. extern "C" { -void AbslInternalSleepFor(absl::Duration duration); +void ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(absl::Duration duration); } // extern "C" inline void absl::SleepFor(absl::Duration duration) { - AbslInternalSleepFor(duration); + ABSL_INTERNAL_C_SYMBOL(AbslInternalSleepFor)(duration); } #endif // ABSL_TIME_CLOCK_H_ -- cgit v1.2.3