diff options
115 files changed, 2061 insertions, 1476 deletions
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index 32b51411..8e6e21dc 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake @@ -462,8 +462,14 @@ set(ABSL_INTERNAL_DLL_TARGETS "container_common" "container_memory" "cord" + "cord_internal" + "cordz_functions" + "cordz_handle" + "cordz_info" + "cordz_sample_token" "core_headers" "counting_allocator" + "crc_cord_state" "crc_cpu_detect" "crc_internal" "crc32c" @@ -518,6 +524,7 @@ set(ABSL_INTERNAL_DLL_TARGETS "log_internal_structured" "log_severity" "log_structured" + "low_level_hash" "malloc_internal" "memory" "meta" @@ -569,8 +576,10 @@ set(ABSL_INTERNAL_DLL_TARGETS "stack_consumption" "stacktrace" "status" + "statusor" "str_format" "str_format_internal" + "strerror" "strings" "strings_internal" "symbolize" @@ -589,6 +598,10 @@ set(ABSL_INTERNAL_TEST_DLL_FILES "hash/hash_testing.h" "log/scoped_mock_log.cc" "log/scoped_mock_log.h" + "random/internal/chi_square.cc" + "random/internal/chi_square.h" + "random/internal/distribution_test_util.cc" + "random/internal/distribution_test_util.h" "random/internal/mock_helpers.h" "random/internal/mock_overload_set.h" "random/mocking_bit_gen.h" @@ -602,6 +615,7 @@ set(ABSL_INTERNAL_TEST_DLL_TARGETS "cordz_test_helpers" "hash_testing" "random_mocking_bit_gen" + "random_internal_distribution_test_util" "random_internal_mock_overload_set" "scoped_mock_log" ) diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake index f1b3158c..de63531b 100644 --- a/CMake/AbseilHelpers.cmake +++ b/CMake/AbseilHelpers.cmake @@ -413,6 +413,10 @@ function(absl_cc_test) DEPS ${ABSL_CC_TEST_DEPS} OUTPUT ABSL_CC_TEST_DEPS ) + absl_internal_dll_targets( + DEPS ${ABSL_CC_TEST_LINKOPTS} + OUTPUT ABSL_CC_TEST_LINKOPTS + ) else() target_compile_definitions(${_NAME} PUBLIC diff --git a/absl/base/attributes.h b/absl/base/attributes.h index 3e5aafba..cb3f367f 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h @@ -685,6 +685,28 @@ #define ABSL_DEPRECATED(message) #endif +// When deprecating Abseil code, it is sometimes necessary to turn off the +// warning within Abseil, until the deprecated code is actually removed. The +// deprecated code can be surrounded with these directives to acheive that +// result. +// +// class ABSL_DEPRECATED("Use Bar instead") Foo; +// +// ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING +// Baz ComputeBazFromFoo(Foo f); +// ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING +#if defined(__GNUC__) || defined(__clang__) +// Clang also supports these GCC pragmas. +#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING \ + _Pragma("GCC diagnostic pop") +#else +#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING +#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING +#endif // defined(__GNUC__) || defined(__clang__) + // ABSL_CONST_INIT // // A variable declaration annotated with the `ABSL_CONST_INIT` attribute will diff --git a/absl/base/internal/raw_logging.h b/absl/base/internal/raw_logging.h index e8765254..3f852d31 100644 --- a/absl/base/internal/raw_logging.h +++ b/absl/base/internal/raw_logging.h @@ -129,7 +129,7 @@ void RawLog(absl::LogSeverity severity, const char* file, int line, const char* format, ...) ABSL_PRINTF_ATTRIBUTE(4, 5); // Writes the provided buffer directly to stderr, in a signal-safe, low-level -// manner. +// manner. Preserves errno. void AsyncSignalSafeWriteToStderr(const char* s, size_t len); // compile-time function to get the "base" filename, that is, the part of diff --git a/absl/base/internal/sysinfo.cc b/absl/base/internal/sysinfo.cc index 8429fb90..7de8ead2 100644 --- a/absl/base/internal/sysinfo.cc +++ b/absl/base/internal/sysinfo.cc @@ -41,6 +41,7 @@ #include <string.h> #include <cassert> +#include <cerrno> #include <cstdint> #include <cstdio> #include <cstdlib> @@ -225,8 +226,8 @@ static int64_t ReadMonotonicClockNanos() { int rc = clock_gettime(CLOCK_MONOTONIC, &t); #endif if (rc != 0) { - perror("clock_gettime() failed"); - abort(); + ABSL_INTERNAL_LOG( + FATAL, "clock_gettime() failed: (" + std::to_string(errno) + ")"); } return int64_t{t.tv_sec} * 1000000000 + t.tv_nsec; } @@ -414,82 +415,24 @@ pid_t GetTID() { return tid; } -#else +#elif defined(__APPLE__) -// Fallback implementation of GetTID using pthread_getspecific. -ABSL_CONST_INIT static once_flag tid_once; -ABSL_CONST_INIT static pthread_key_t tid_key; -ABSL_CONST_INIT static absl::base_internal::SpinLock tid_lock( - absl::kConstInit, base_internal::SCHEDULE_KERNEL_ONLY); - -// We set a bit per thread in this array to indicate that an ID is in -// use. ID 0 is unused because it is the default value returned by -// pthread_getspecific(). -ABSL_CONST_INIT static std::vector<uint32_t> *tid_array - ABSL_GUARDED_BY(tid_lock) = nullptr; -static constexpr int kBitsPerWord = 32; // tid_array is uint32_t. - -// Returns the TID to tid_array. -static void FreeTID(void *v) { - intptr_t tid = reinterpret_cast<intptr_t>(v); - intptr_t word = tid / kBitsPerWord; - uint32_t mask = ~(1u << (tid % kBitsPerWord)); - absl::base_internal::SpinLockHolder lock(&tid_lock); - assert(0 <= word && static_cast<size_t>(word) < tid_array->size()); - (*tid_array)[static_cast<size_t>(word)] &= mask; +pid_t GetTID() { + uint64_t tid; + // `nullptr` here implies this thread. This only fails if the specified + // thread is invalid or the pointer-to-tid is null, so we needn't worry about + // it. + pthread_threadid_np(nullptr, &tid); + return static_cast<pid_t>(tid); } -static void InitGetTID() { - if (pthread_key_create(&tid_key, FreeTID) != 0) { - // The logging system calls GetTID() so it can't be used here. - perror("pthread_key_create failed"); - abort(); - } - - // Initialize tid_array. - absl::base_internal::SpinLockHolder lock(&tid_lock); - tid_array = new std::vector<uint32_t>(1); - (*tid_array)[0] = 1; // ID 0 is never-allocated. -} +#else -// Return a per-thread small integer ID from pthread's thread-specific data. +// Fallback implementation of `GetTID` using `pthread_self`. pid_t GetTID() { - absl::call_once(tid_once, InitGetTID); - - intptr_t tid = reinterpret_cast<intptr_t>(pthread_getspecific(tid_key)); - if (tid != 0) { - return static_cast<pid_t>(tid); - } - - int bit; // tid_array[word] = 1u << bit; - size_t word; - { - // Search for the first unused ID. - absl::base_internal::SpinLockHolder lock(&tid_lock); - // First search for a word in the array that is not all ones. - word = 0; - while (word < tid_array->size() && ~(*tid_array)[word] == 0) { - ++word; - } - if (word == tid_array->size()) { - tid_array->push_back(0); // No space left, add kBitsPerWord more IDs. - } - // Search for a zero bit in the word. - bit = 0; - while (bit < kBitsPerWord && (((*tid_array)[word] >> bit) & 1) != 0) { - ++bit; - } - tid = - static_cast<intptr_t>((word * kBitsPerWord) + static_cast<size_t>(bit)); - (*tid_array)[word] |= 1u << bit; // Mark the TID as allocated. - } - - if (pthread_setspecific(tid_key, reinterpret_cast<void *>(tid)) != 0) { - perror("pthread_setspecific failed"); - abort(); - } - - return static_cast<pid_t>(tid); + // `pthread_t` need not be arithmetic per POSIX; platforms where it isn't + // should be handled above. + return static_cast<pid_t>(pthread_self()); } #endif diff --git a/absl/container/BUILD.bazel b/absl/container/BUILD.bazel index 902f6ed3..f22da59a 100644 --- a/absl/container/BUILD.bazel +++ b/absl/container/BUILD.bazel @@ -160,8 +160,8 @@ cc_test( "//absl/base:config", "//absl/base:core_headers", "//absl/base:exception_testing", - "//absl/base:raw_logging_internal", "//absl/hash:hash_testing", + "//absl/log:check", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -255,7 +255,7 @@ cc_test( ":unordered_map_lookup_test", ":unordered_map_members_test", ":unordered_map_modifiers_test", - "//absl/base:raw_logging_internal", + "//absl/log:check", "//absl/types:any", "@com_google_googletest//:gtest_main", ], @@ -289,7 +289,7 @@ cc_test( ":unordered_set_lookup_test", ":unordered_set_members_test", ":unordered_set_modifiers_test", - "//absl/base:raw_logging_internal", + "//absl/log:check", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -656,7 +656,6 @@ cc_test( "//absl/base:config", "//absl/base:core_headers", "//absl/base:prefetch", - "//absl/base:raw_logging_internal", "//absl/log", "//absl/strings", "@com_google_googletest//:gtest_main", @@ -743,7 +742,7 @@ cc_test( ":layout", "//absl/base:config", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log:check", "//absl/types:span", "@com_google_googletest//:gtest_main", ], diff --git a/absl/container/CMakeLists.txt b/absl/container/CMakeLists.txt index 3c48270b..39d95e02 100644 --- a/absl/container/CMakeLists.txt +++ b/absl/container/CMakeLists.txt @@ -221,16 +221,16 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS - absl::counting_allocator - absl::inlined_vector - absl::test_instance_tracker + absl::check absl::config absl::core_headers + absl::counting_allocator absl::exception_testing absl::hash_testing + absl::inlined_vector absl::memory - absl::raw_logging_internal absl::strings + absl::test_instance_tracker GTest::gmock_main ) @@ -300,14 +300,14 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS + absl::any + absl::check absl::flat_hash_map absl::hash_generator_testing absl::unordered_map_constructor_test absl::unordered_map_lookup_test absl::unordered_map_members_test absl::unordered_map_modifiers_test - absl::any - absl::raw_logging_internal GTest::gmock_main ) @@ -337,15 +337,15 @@ absl_cc_test( ${ABSL_TEST_COPTS} "-DUNORDERED_SET_CXX17" DEPS + absl::check absl::flat_hash_set absl::hash_generator_testing + absl::memory + absl::strings absl::unordered_set_constructor_test absl::unordered_set_lookup_test absl::unordered_set_members_test absl::unordered_set_modifiers_test - absl::memory - absl::raw_logging_internal - absl::strings GTest::gmock_main ) @@ -742,7 +742,6 @@ absl_cc_test( absl::log absl::prefetch absl::raw_hash_set - absl::raw_logging_internal absl::strings GTest::gmock_main ) @@ -788,9 +787,9 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::layout + absl::check absl::config absl::core_headers - absl::raw_logging_internal absl::span GTest::gmock_main ) diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index e99137a4..9f1c813d 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h @@ -117,14 +117,20 @@ class FixedArray { (N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type) : static_cast<size_type>(N)); - FixedArray( - const FixedArray& other, - const allocator_type& a = allocator_type()) noexcept(NoexceptCopyable()) + FixedArray(const FixedArray& other) noexcept(NoexceptCopyable()) + : FixedArray(other, + AllocatorTraits::select_on_container_copy_construction( + other.storage_.alloc())) {} + + FixedArray(const FixedArray& other, + const allocator_type& a) noexcept(NoexceptCopyable()) : FixedArray(other.begin(), other.end(), a) {} - FixedArray( - FixedArray&& other, - const allocator_type& a = allocator_type()) noexcept(NoexceptMovable()) + FixedArray(FixedArray&& other) noexcept(NoexceptMovable()) + : FixedArray(std::move(other), other.storage_.alloc()) {} + + FixedArray(FixedArray&& other, + const allocator_type& a) noexcept(NoexceptMovable()) : FixedArray(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()), a) {} @@ -480,6 +486,9 @@ class FixedArray { StorageElement* begin() const { return data_; } StorageElement* end() const { return begin() + size(); } allocator_type& alloc() { return size_alloc_.template get<1>(); } + const allocator_type& alloc() const { + return size_alloc_.template get<1>(); + } private: static bool UsingInlinedStorage(size_type n) { diff --git a/absl/container/fixed_array_test.cc b/absl/container/fixed_array_test.cc index 49598e7a..9dbf2a84 100644 --- a/absl/container/fixed_array_test.cc +++ b/absl/container/fixed_array_test.cc @@ -768,6 +768,22 @@ TEST(AllocatorSupportTest, SizeValAllocConstructor) { } } +TEST(AllocatorSupportTest, PropagatesStatefulAllocator) { + constexpr size_t inlined_size = 4; + using Alloc = absl::container_internal::CountingAllocator<int>; + using AllocFxdArr = absl::FixedArray<int, inlined_size, Alloc>; + + auto len = inlined_size * 2; + auto val = 0; + int64_t allocated = 0; + AllocFxdArr arr(len, val, Alloc(&allocated)); + + EXPECT_EQ(allocated, len * sizeof(int)); + + AllocFxdArr copy = arr; + EXPECT_EQ(allocated, len * sizeof(int) * 2); +} + #ifdef ABSL_HAVE_ADDRESS_SANITIZER TEST(FixedArrayTest, AddressSanitizerAnnotations1) { absl::FixedArray<int, 32> a(10); diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index 03171f6d..e6acbea2 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc @@ -16,12 +16,12 @@ #include <memory> -#include "absl/base/internal/raw_logging.h" #include "absl/container/internal/hash_generator_testing.h" #include "absl/container/internal/unordered_map_constructor_test.h" #include "absl/container/internal/unordered_map_lookup_test.h" #include "absl/container/internal/unordered_map_members_test.h" #include "absl/container/internal/unordered_map_modifiers_test.h" +#include "absl/log/check.h" #include "absl/types/any.h" namespace absl { @@ -40,10 +40,10 @@ struct BeforeMain { BeforeMain() { absl::flat_hash_map<int, int> x; x.insert({1, 1}); - ABSL_RAW_CHECK(x.find(0) == x.end(), "x should not contain 0"); + CHECK(x.find(0) == x.end()) << "x should not contain 0"; auto it = x.find(1); - ABSL_RAW_CHECK(it != x.end(), "x should contain 1"); - ABSL_RAW_CHECK(it->second, "1 should map to 1"); + CHECK(it != x.end()) << "x should contain 1"; + CHECK(it->second) << "1 should map to 1"; } }; const BeforeMain before_main; diff --git a/absl/container/flat_hash_set_test.cc b/absl/container/flat_hash_set_test.cc index b6a72a20..20130f91 100644 --- a/absl/container/flat_hash_set_test.cc +++ b/absl/container/flat_hash_set_test.cc @@ -16,12 +16,12 @@ #include <vector> -#include "absl/base/internal/raw_logging.h" #include "absl/container/internal/hash_generator_testing.h" #include "absl/container/internal/unordered_set_constructor_test.h" #include "absl/container/internal/unordered_set_lookup_test.h" #include "absl/container/internal/unordered_set_members_test.h" #include "absl/container/internal/unordered_set_modifiers_test.h" +#include "absl/log/check.h" #include "absl/memory/memory.h" #include "absl/strings/string_view.h" @@ -42,8 +42,8 @@ struct BeforeMain { BeforeMain() { absl::flat_hash_set<int> x; x.insert(1); - ABSL_RAW_CHECK(!x.contains(0), "x should not contain 0"); - ABSL_RAW_CHECK(x.contains(1), "x should contain 1"); + CHECK(!x.contains(0)) << "x should not contain 0"; + CHECK(x.contains(1)) << "x should contain 1"; } }; const BeforeMain before_main; diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 808f97cc..6f4625dc 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -31,12 +31,12 @@ #include "gtest/gtest.h" #include "absl/base/attributes.h" #include "absl/base/internal/exception_testing.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" #include "absl/base/options.h" #include "absl/container/internal/counting_allocator.h" #include "absl/container/internal/test_instance_tracker.h" #include "absl/hash/hash_testing.h" +#include "absl/log/check.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" @@ -103,13 +103,13 @@ class RefCounted { } void Ref() const { - ABSL_RAW_CHECK(count_ != nullptr, ""); + CHECK_NE(count_, nullptr); ++(*count_); } void Unref() const { --(*count_); - ABSL_RAW_CHECK(*count_ >= 0, ""); + CHECK_GE(*count_, 0); } int value_; diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc index 54e5d5bb..ce599ce7 100644 --- a/absl/container/internal/layout_test.cc +++ b/absl/container/internal/layout_test.cc @@ -26,7 +26,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/check.h" #include "absl/types/span.h" namespace absl { @@ -38,7 +38,7 @@ using ::absl::Span; using ::testing::ElementsAre; size_t Distance(const void* from, const void* to) { - ABSL_RAW_CHECK(from <= to, "Distance must be non-negative"); + CHECK_LE(from, to) << "Distance must be non-negative"; return static_cast<const char*>(to) - static_cast<const char*>(from); } @@ -366,7 +366,7 @@ TEST(Layout, Sizes) { } TEST(Layout, PointerByIndex) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ(0, Distance(p, Type<const int32_t*>(L::Partial().Pointer<0>(p)))); @@ -447,7 +447,7 @@ TEST(Layout, PointerByIndex) { } TEST(Layout, PointerByType) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ( @@ -526,7 +526,7 @@ TEST(Layout, PointerByType) { } TEST(Layout, MutablePointerByIndex) { - alignas(max_align_t) unsigned char p[100]; + alignas(max_align_t) unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<0>(p)))); @@ -581,7 +581,7 @@ TEST(Layout, MutablePointerByIndex) { } TEST(Layout, MutablePointerByType) { - alignas(max_align_t) unsigned char p[100]; + alignas(max_align_t) unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ(0, Distance(p, Type<int32_t*>(L::Partial().Pointer<int32_t>(p)))); @@ -647,7 +647,7 @@ TEST(Layout, MutablePointerByType) { } TEST(Layout, Pointers) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; using L = Layout<int8_t, int8_t, Int128>; { const auto x = L::Partial(); @@ -683,7 +683,7 @@ TEST(Layout, Pointers) { } TEST(Layout, MutablePointers) { - alignas(max_align_t) unsigned char p[100]; + alignas(max_align_t) unsigned char p[100] = {0}; using L = Layout<int8_t, int8_t, Int128>; { const auto x = L::Partial(); @@ -716,7 +716,7 @@ TEST(Layout, MutablePointers) { } TEST(Layout, SliceByIndexSize) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size()); @@ -744,7 +744,7 @@ TEST(Layout, SliceByIndexSize) { } TEST(Layout, SliceByTypeSize) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size()); @@ -766,7 +766,7 @@ TEST(Layout, SliceByTypeSize) { } TEST(Layout, MutableSliceByIndexSize) { - alignas(max_align_t) unsigned char p[100]; + alignas(max_align_t) unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size()); @@ -794,7 +794,7 @@ TEST(Layout, MutableSliceByIndexSize) { } TEST(Layout, MutableSliceByTypeSize) { - alignas(max_align_t) unsigned char p[100]; + alignas(max_align_t) unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ(0, L::Partial(0).Slice<int32_t>(p).size()); @@ -816,7 +816,7 @@ TEST(Layout, MutableSliceByTypeSize) { } TEST(Layout, SliceByIndexData) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ( @@ -939,7 +939,7 @@ TEST(Layout, SliceByIndexData) { } TEST(Layout, SliceByTypeData) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ( @@ -1037,7 +1037,7 @@ TEST(Layout, SliceByTypeData) { } TEST(Layout, MutableSliceByIndexData) { - alignas(max_align_t) unsigned char p[100]; + alignas(max_align_t) unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ( @@ -1122,7 +1122,7 @@ TEST(Layout, MutableSliceByIndexData) { } TEST(Layout, MutableSliceByTypeData) { - alignas(max_align_t) unsigned char p[100]; + alignas(max_align_t) unsigned char p[100] = {0}; { using L = Layout<int32_t>; EXPECT_EQ( @@ -1268,7 +1268,7 @@ testing::PolymorphicMatcher<TupleMatcher<M...>> Tuple(M... matchers) { } TEST(Layout, Slices) { - alignas(max_align_t) const unsigned char p[100] = {}; + alignas(max_align_t) const unsigned char p[100] = {0}; using L = Layout<int8_t, int8_t, Int128>; { const auto x = L::Partial(); @@ -1302,7 +1302,7 @@ TEST(Layout, Slices) { } TEST(Layout, MutableSlices) { - alignas(max_align_t) unsigned char p[100] = {}; + alignas(max_align_t) unsigned char p[100] = {0}; using L = Layout<int8_t, int8_t, Int128>; { const auto x = L::Partial(); diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 21b161b3..03f236f2 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -1644,9 +1644,9 @@ class raw_hash_set { // Note: can't use `= default` due to non-default noexcept (causes // problems for some compilers). NOLINTNEXTLINE raw_hash_set() noexcept( - std::is_nothrow_default_constructible<hasher>::value&& - std::is_nothrow_default_constructible<key_equal>::value&& - std::is_nothrow_default_constructible<allocator_type>::value) {} + std::is_nothrow_default_constructible<hasher>::value && + std::is_nothrow_default_constructible<key_equal>::value && + std::is_nothrow_default_constructible<allocator_type>::value) {} ABSL_ATTRIBUTE_NOINLINE explicit raw_hash_set( size_t bucket_count, const hasher& hash = hasher(), @@ -1772,9 +1772,9 @@ class raw_hash_set { } ABSL_ATTRIBUTE_NOINLINE raw_hash_set(raw_hash_set&& that) noexcept( - std::is_nothrow_copy_constructible<hasher>::value&& - std::is_nothrow_copy_constructible<key_equal>::value&& - std::is_nothrow_copy_constructible<allocator_type>::value) + std::is_nothrow_copy_constructible<hasher>::value && + std::is_nothrow_copy_constructible<key_equal>::value && + std::is_nothrow_copy_constructible<allocator_type>::value) : // Hash, equality and allocator are copied instead of moved because // `that` must be left valid. If Hash is std::function<Key>, moving it // would create a nullptr functor that cannot be called. @@ -1803,9 +1803,9 @@ class raw_hash_set { } raw_hash_set& operator=(raw_hash_set&& that) noexcept( - absl::allocator_traits<allocator_type>::is_always_equal::value&& - std::is_nothrow_move_assignable<hasher>::value&& - std::is_nothrow_move_assignable<key_equal>::value) { + absl::allocator_traits<allocator_type>::is_always_equal::value && + std::is_nothrow_move_assignable<hasher>::value && + std::is_nothrow_move_assignable<key_equal>::value) { // TODO(sbenza): We should only use the operations from the noexcept clause // to make sure we actually adhere to that contract. // NOLINTNEXTLINE: not returning *this for performance. diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index c46a5939..ce1070ba 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc @@ -40,7 +40,6 @@ #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/internal/cycleclock.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/prefetch.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" @@ -1280,7 +1279,7 @@ ExpectedStats XorSeedExpectedStats() { {{0.95, 0}, {0.99, 1}, {0.999, 4}, {0.9999, 10}}}; } } - ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); + LOG(FATAL) << "Unknown Group width"; return {}; } @@ -1376,7 +1375,7 @@ ExpectedStats LinearTransformExpectedStats() { {{0.95, 0}, {0.99, 1}, {0.999, 6}, {0.9999, 10}}}; } } - ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); + LOG(FATAL) << "Unknown Group width"; return {}; } diff --git a/absl/copts/AbseilConfigureCopts.cmake b/absl/copts/AbseilConfigureCopts.cmake index 8209b262..3f737c81 100644 --- a/absl/copts/AbseilConfigureCopts.cmake +++ b/absl/copts/AbseilConfigureCopts.cmake @@ -83,6 +83,16 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # MATCHES so we get both Clang an set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_LLVM_TEST_FLAGS}") endif() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") + # IntelLLVM is similar to Clang, with some additional flags. + if(MSVC) + # clang-cl is half MSVC, half LLVM + set(ABSL_DEFAULT_COPTS "${ABSL_CLANG_CL_FLAGS}") + set(ABSL_TEST_COPTS "${ABSL_CLANG_CL_TEST_FLAGS}") + else() + set(ABSL_DEFAULT_COPTS "${ABSL_LLVM_FLAGS}") + set(ABSL_TEST_COPTS "${ABSL_LLVM_TEST_FLAGS}") + endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(ABSL_DEFAULT_COPTS "${ABSL_MSVC_FLAGS}") set(ABSL_TEST_COPTS "${ABSL_MSVC_TEST_FLAGS}") diff --git a/absl/crc/internal/cpu_detect.cc b/absl/crc/internal/cpu_detect.cc index d61b7018..83838085 100644 --- a/absl/crc/internal/cpu_detect.cc +++ b/absl/crc/internal/cpu_detect.cc @@ -28,15 +28,12 @@ #include <intrin.h> #endif -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace crc_internal { - #if defined(__x86_64__) || defined(_M_X64) - -namespace { - -#if !defined(_WIN32) && !defined(_WIN64) +#if ABSL_HAVE_BUILTIN(__cpuid) +// MSVC-equivalent __cpuid intrinsic declaration for clang-like compilers +// for non-Windows build environments. +extern void __cpuid(int[4], int); +#elif !defined(_WIN32) && !defined(_WIN64) // MSVC defines this function for us. // https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex static void __cpuid(int cpu_info[4], int info_type) { @@ -46,6 +43,15 @@ static void __cpuid(int cpu_info[4], int info_type) { : "a"(info_type), "c"(0)); } #endif // !defined(_WIN32) && !defined(_WIN64) +#endif // defined(__x86_64__) || defined(_M_X64) + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace crc_internal { + +#if defined(__x86_64__) || defined(_M_X64) + +namespace { enum class Vendor { kUnknown, diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel index 86063da2..42124bfb 100644 --- a/absl/debugging/BUILD.bazel +++ b/absl/debugging/BUILD.bazel @@ -49,6 +49,7 @@ cc_library( ":debugging_internal", "//absl/base:config", "//absl/base:core_headers", + "//absl/base:dynamic_annotations", "//absl/base:raw_logging_internal", ], ) @@ -121,7 +122,8 @@ cc_test( "//absl/base", "//absl/base:config", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log", + "//absl/log:check", "//absl/memory", "//absl/strings", "@com_google_googletest//:gtest", @@ -179,6 +181,7 @@ cc_test( ":stacktrace", ":symbolize", "//absl/base:raw_logging_internal", + "//absl/log:check", "//absl/strings", "@com_google_googletest//:gtest", ], @@ -232,7 +235,7 @@ cc_test( ":stack_consumption", "//absl/base:config", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/memory", "@com_google_googletest//:gtest_main", ], @@ -259,7 +262,7 @@ cc_test( deps = [ ":leak_check", "//absl/base:config", - "//absl/base:raw_logging_internal", + "//absl/log", "@com_google_googletest//:gtest_main", ], ) @@ -276,7 +279,7 @@ cc_binary( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":leak_check", - "//absl/base:raw_logging_internal", + "//absl/log", "@com_google_googletest//:gtest_main", ], ) @@ -305,7 +308,7 @@ cc_test( deps = [ ":stack_consumption", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt index 8f29cc07..65e2af88 100644 --- a/absl/debugging/CMakeLists.txt +++ b/absl/debugging/CMakeLists.txt @@ -41,6 +41,7 @@ absl_cc_library( absl::debugging_internal absl::config absl::core_headers + absl::dynamic_annotations absl::raw_logging_internal PUBLIC ) @@ -100,14 +101,15 @@ absl_cc_test( LINKOPTS $<$<BOOL:${MSVC}>:-DEBUG> DEPS - absl::stack_consumption - absl::symbolize absl::base + absl::check absl::config absl::core_headers + absl::log absl::memory - absl::raw_logging_internal + absl::stack_consumption absl::strings + absl::symbolize GTest::gmock ) @@ -156,6 +158,7 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS + absl::check absl::failure_signal_handler absl::stacktrace absl::symbolize @@ -215,8 +218,8 @@ absl_cc_test( absl::stack_consumption absl::config absl::core_headers + absl::log absl::memory - absl::raw_logging_internal GTest::gmock_main ) @@ -247,6 +250,7 @@ absl_cc_test( DEPS absl::leak_check absl::base + absl::log GTest::gmock_main ) @@ -277,7 +281,7 @@ absl_cc_test( DEPS absl::stack_consumption absl::core_headers - absl::raw_logging_internal + absl::log GTest::gmock_main ) diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index 9f399d02..0db2a896 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc @@ -236,10 +236,6 @@ static void InstallOneFailureHandler(FailureSignalData* data, #endif -static void WriteToStderr(const char* data) { - absl::raw_log_internal::AsyncSignalSafeWriteToStderr(data, strlen(data)); -} - static void WriteSignalMessage(int signo, int cpu, void (*writerfn)(const char*)) { char buf[96]; @@ -380,7 +376,11 @@ static void AbslFailureSignalHandler(int signo, siginfo_t*, void* ucontext) { #endif // First write to stderr. - WriteFailureInfo(signo, ucontext, my_cpu, WriteToStderr); + WriteFailureInfo( + signo, ucontext, my_cpu, +[](const char* data) { + absl::raw_log_internal::AsyncSignalSafeWriteToStderr(data, + strlen(data)); + }); // Riskier code (because it is less likely to be async-signal-safe) // goes after this point. diff --git a/absl/debugging/failure_signal_handler_test.cc b/absl/debugging/failure_signal_handler_test.cc index 6a62428b..72816a3e 100644 --- a/absl/debugging/failure_signal_handler_test.cc +++ b/absl/debugging/failure_signal_handler_test.cc @@ -22,11 +22,12 @@ #include <cstring> #include <fstream> -#include "gtest/gtest.h" #include "gmock/gmock.h" +#include "gtest/gtest.h" #include "absl/base/internal/raw_logging.h" #include "absl/debugging/stacktrace.h" #include "absl/debugging/symbolize.h" +#include "absl/log/check.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" @@ -87,7 +88,7 @@ std::string GetTmpDir() { // This function runs in a fork()ed process on most systems. void InstallHandlerWithWriteToFileAndRaise(const char* file, int signo) { error_file = fopen(file, "w"); - ABSL_RAW_CHECK(error_file != nullptr, "Failed create error_file"); + CHECK_NE(error_file, nullptr) << "Failed create error_file"; absl::FailureSignalHandlerOptions options; options.writerfn = WriteToErrorFile; absl::InstallFailureSignalHandler(options); diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 2fa4143a..faec72b5 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -19,8 +19,8 @@ #include "gtest/gtest.h" #include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" #include "absl/debugging/internal/stack_consumption.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" namespace absl { @@ -151,7 +151,7 @@ static const char *DemangleStackConsumption(const char *mangled, int *stack_consumed) { g_mangled = mangled; *stack_consumed = GetSignalHandlerStackConsumption(DemangleSignalHandler); - ABSL_RAW_LOG(INFO, "Stack consumption of Demangle: %d", *stack_consumed); + LOG(INFO) << "Stack consumption of Demangle: " << *stack_consumed; return g_demangle_result; } diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h index 113071a9..5f4537ba 100644 --- a/absl/debugging/internal/elf_mem_image.h +++ b/absl/debugging/internal/elf_mem_image.h @@ -33,7 +33,7 @@ #if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) && \ !defined(__native_client__) && !defined(__asmjs__) && \ - !defined(__wasm__) && !defined(__HAIKU__) + !defined(__wasm__) && !defined(__HAIKU__) && !defined(__sun) #define ABSL_HAVE_ELF_MEM_IMAGE 1 #endif diff --git a/absl/debugging/internal/stack_consumption_test.cc b/absl/debugging/internal/stack_consumption_test.cc index 80445bf4..0255ac8f 100644 --- a/absl/debugging/internal/stack_consumption_test.cc +++ b/absl/debugging/internal/stack_consumption_test.cc @@ -20,7 +20,7 @@ #include <string.h> #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -33,7 +33,7 @@ static void SimpleSignalHandler(int signo) { // Never true, but prevents compiler from optimizing buf out. if (signo == 0) { - ABSL_RAW_LOG(INFO, "%p", static_cast<void*>(buf)); + LOG(INFO) << static_cast<void*>(buf); } } diff --git a/absl/debugging/leak_check_fail_test.cc b/absl/debugging/leak_check_fail_test.cc index c49b81a9..46e9fb62 100644 --- a/absl/debugging/leak_check_fail_test.cc +++ b/absl/debugging/leak_check_fail_test.cc @@ -13,9 +13,10 @@ // limitations under the License. #include <memory> + #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" #include "absl/debugging/leak_check.h" +#include "absl/log/log.h" namespace { @@ -25,7 +26,7 @@ TEST(LeakCheckTest, LeakMemory) { // failed exit code. char* foo = strdup("lsan should complain about this leaked string"); - ABSL_RAW_LOG(INFO, "Should detect leaked string %s", foo); + LOG(INFO) << "Should detect leaked string " << foo; } TEST(LeakCheckTest, LeakMemoryAfterDisablerScope) { @@ -34,8 +35,7 @@ TEST(LeakCheckTest, LeakMemoryAfterDisablerScope) { // failed exit code. { absl::LeakCheckDisabler disabler; } char* foo = strdup("lsan should also complain about this leaked string"); - ABSL_RAW_LOG(INFO, "Re-enabled leak detection.Should detect leaked string %s", - foo); + LOG(INFO) << "Re-enabled leak detection.Should detect leaked string " << foo; } } // namespace diff --git a/absl/debugging/leak_check_test.cc b/absl/debugging/leak_check_test.cc index 6a42e31b..6f0135ed 100644 --- a/absl/debugging/leak_check_test.cc +++ b/absl/debugging/leak_check_test.cc @@ -16,8 +16,8 @@ #include "gtest/gtest.h" #include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" #include "absl/debugging/leak_check.h" +#include "absl/log/log.h" namespace { @@ -26,7 +26,7 @@ TEST(LeakCheckTest, IgnoreLeakSuppressesLeakedMemoryErrors) { GTEST_SKIP() << "LeakChecker is not active"; } auto foo = absl::IgnoreLeak(new std::string("some ignored leaked string")); - ABSL_RAW_LOG(INFO, "Ignoring leaked string %s", foo->c_str()); + LOG(INFO) << "Ignoring leaked string " << foo; } TEST(LeakCheckTest, LeakCheckDisablerIgnoresLeak) { @@ -35,7 +35,7 @@ TEST(LeakCheckTest, LeakCheckDisablerIgnoresLeak) { } absl::LeakCheckDisabler disabler; auto foo = new std::string("some string leaked while checks are disabled"); - ABSL_RAW_LOG(INFO, "Ignoring leaked string %s", foo->c_str()); + LOG(INFO) << "Ignoring leaked string " << foo; } } // namespace diff --git a/absl/debugging/symbolize_test.cc b/absl/debugging/symbolize_test.cc index 3165c6ed..1d1199ff 100644 --- a/absl/debugging/symbolize_test.cc +++ b/absl/debugging/symbolize_test.cc @@ -29,9 +29,10 @@ #include "absl/base/casts.h" #include "absl/base/config.h" #include "absl/base/internal/per_thread_tls.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/optimization.h" #include "absl/debugging/internal/stack_consumption.h" +#include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/strings/string_view.h" @@ -124,15 +125,17 @@ static char try_symbolize_buffer[4096]; // absl::Symbolize() returns false, otherwise returns try_symbolize_buffer with // the result of absl::Symbolize(). static const char *TrySymbolizeWithLimit(void *pc, int limit) { - ABSL_RAW_CHECK(limit <= sizeof(try_symbolize_buffer), - "try_symbolize_buffer is too small"); + CHECK_LE(limit, sizeof(try_symbolize_buffer)) + << "try_symbolize_buffer is too small"; // Use the heap to facilitate heap and buffer sanitizer tools. auto heap_buffer = absl::make_unique<char[]>(sizeof(try_symbolize_buffer)); bool found = absl::Symbolize(pc, heap_buffer.get(), limit); if (found) { - ABSL_RAW_CHECK(strnlen(heap_buffer.get(), limit) < limit, - "absl::Symbolize() did not properly terminate the string"); + CHECK_LT(static_cast<int>( + strnlen(heap_buffer.get(), static_cast<size_t>(limit))), + limit) + << "absl::Symbolize() did not properly terminate the string"; strncpy(try_symbolize_buffer, heap_buffer.get(), sizeof(try_symbolize_buffer) - 1); try_symbolize_buffer[sizeof(try_symbolize_buffer) - 1] = '\0'; @@ -155,8 +158,8 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithReturnAddress() { #if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE) void *return_address = __builtin_return_address(0); const char *symbol = TrySymbolize(return_address); - ABSL_RAW_CHECK(symbol != nullptr, "TestWithReturnAddress failed"); - ABSL_RAW_CHECK(strcmp(symbol, "main") == 0, "TestWithReturnAddress failed"); + CHECK_NE(symbol, nullptr) << "TestWithReturnAddress failed"; + CHECK_STREQ(symbol, "main") << "TestWithReturnAddress failed"; std::cout << "TestWithReturnAddress passed" << std::endl; #endif } @@ -314,8 +317,8 @@ static int FilterElfHeader(struct dl_phdr_info *info, size_t size, void *data) { TEST(Symbolize, SymbolizeWithMultipleMaps) { // Force kPadding0 and kPadding1 to be linked in. if (volatile_bool) { - ABSL_RAW_LOG(INFO, "%s", kPadding0); - ABSL_RAW_LOG(INFO, "%s", kPadding1); + LOG(INFO) << kPadding0; + LOG(INFO) << kPadding1; } // Verify we can symbolize everything. @@ -463,9 +466,9 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() { (defined(__i386__) || defined(__x86_64__)) void *pc = non_inline_func(); const char *symbol = TrySymbolize(pc); - ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideNonInlineFunction failed"); - ABSL_RAW_CHECK(strcmp(symbol, "non_inline_func") == 0, - "TestWithPCInsideNonInlineFunction failed"); + CHECK_NE(symbol, nullptr) << "TestWithPCInsideNonInlineFunction failed"; + CHECK_STREQ(symbol, "non_inline_func") + << "TestWithPCInsideNonInlineFunction failed"; std::cout << "TestWithPCInsideNonInlineFunction passed" << std::endl; #endif } @@ -475,9 +478,8 @@ void ABSL_ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() { (defined(__i386__) || defined(__x86_64__)) void *pc = inline_func(); // Must be inlined. const char *symbol = TrySymbolize(pc); - ABSL_RAW_CHECK(symbol != nullptr, "TestWithPCInsideInlineFunction failed"); - ABSL_RAW_CHECK(strcmp(symbol, __FUNCTION__) == 0, - "TestWithPCInsideInlineFunction failed"); + CHECK_NE(symbol, nullptr) << "TestWithPCInsideInlineFunction failed"; + CHECK_STREQ(symbol, __FUNCTION__) << "TestWithPCInsideInlineFunction failed"; std::cout << "TestWithPCInsideInlineFunction passed" << std::endl; #endif } @@ -519,9 +521,8 @@ __attribute__((target("arm"))) int ArmThumbOverlapArm(int x) { void ABSL_ATTRIBUTE_NOINLINE TestArmThumbOverlap() { #if defined(ABSL_HAVE_ATTRIBUTE_NOINLINE) const char *symbol = TrySymbolize((void *)&ArmThumbOverlapArm); - ABSL_RAW_CHECK(symbol != nullptr, "TestArmThumbOverlap failed"); - ABSL_RAW_CHECK(strcmp("ArmThumbOverlapArm()", symbol) == 0, - "TestArmThumbOverlap failed"); + CHECK_NE(symbol, nullptr) << "TestArmThumbOverlap failed"; + CHECK_STREQ("ArmThumbOverlapArm()", symbol) << "TestArmThumbOverlap failed"; std::cout << "TestArmThumbOverlap passed" << std::endl; #endif } @@ -584,7 +585,7 @@ int main(int argc, char **argv) { #if !defined(__EMSCRIPTEN__) // Make sure kHpageTextPadding is linked into the binary. if (volatile_bool) { - ABSL_RAW_LOG(INFO, "%s", kHpageTextPadding); + LOG(INFO) << kHpageTextPadding; } #endif // !defined(__EMSCRIPTEN__) diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 570d280c..627f453a 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel @@ -452,8 +452,8 @@ cc_test( ":parse", ":reflection", ":usage_internal", - "//absl/base:raw_logging_internal", "//absl/base:scoped_set_env", + "//absl/log", "//absl/strings", "//absl/types:span", "@com_google_googletest//:gtest_main", diff --git a/absl/flags/CMakeLists.txt b/absl/flags/CMakeLists.txt index b5f6dfc4..b9d3b97b 100644 --- a/absl/flags/CMakeLists.txt +++ b/absl/flags/CMakeLists.txt @@ -374,7 +374,7 @@ absl_cc_test( absl::flags_parse absl::flags_reflection absl::flags_usage_internal - absl::raw_logging_internal + absl::log absl::scoped_set_env absl::span absl::strings diff --git a/absl/flags/parse_test.cc b/absl/flags/parse_test.cc index cd32efc8..97b78980 100644 --- a/absl/flags/parse_test.cc +++ b/absl/flags/parse_test.cc @@ -24,12 +24,12 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/internal/scoped_set_env.h" #include "absl/flags/flag.h" #include "absl/flags/internal/parse.h" #include "absl/flags/internal/usage.h" #include "absl/flags/reflection.h" +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" @@ -150,8 +150,7 @@ const std::string& GetTestTempDir() { } if (res->empty()) { - ABSL_INTERNAL_LOG(FATAL, - "Failed to make temporary directory for data files"); + LOG(FATAL) << "Failed to make temporary directory for data files"; } #ifdef _WIN32 diff --git a/absl/functional/CMakeLists.txt b/absl/functional/CMakeLists.txt index 628b2ffc..c704e049 100644 --- a/absl/functional/CMakeLists.txt +++ b/absl/functional/CMakeLists.txt @@ -39,7 +39,7 @@ absl_cc_test( "any_invocable_test.cc" "internal/any_invocable.h" COPTS - ${ABSL_DEFAULT_COPTS} + ${ABSL_TEST_COPTS} DEPS absl::any_invocable absl::base_internal diff --git a/absl/functional/any_invocable_test.cc b/absl/functional/any_invocable_test.cc index 10a4dee5..a740faa6 100644 --- a/absl/functional/any_invocable_test.cc +++ b/absl/functional/any_invocable_test.cc @@ -1418,7 +1418,7 @@ TYPED_TEST_P(AnyInvTestRvalue, NonConstCrashesOnSecondCall) { // Ensure we're still valid EXPECT_TRUE(static_cast<bool>(fun)); // NOLINT(bugprone-use-after-move) -#if !defined(NDEBUG) || ABSL_OPTION_HARDENED == 1 +#if !defined(NDEBUG) EXPECT_DEATH_IF_SUPPORTED(std::move(fun)(7, 8, 9), ""); #endif } diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h index b6a38e37..a52fa876 100644 --- a/absl/functional/internal/any_invocable.h +++ b/absl/functional/internal/any_invocable.h @@ -135,8 +135,16 @@ void InvokeR(F&& f, P&&... args) { template <class ReturnType, class F, class... P, absl::enable_if_t<!std::is_void<ReturnType>::value, int> = 0> ReturnType InvokeR(F&& f, P&&... args) { + // GCC 12 has a false-positive -Wmaybe-uninitialized warning here. +#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif return absl::base_internal::invoke(std::forward<F>(f), std::forward<P>(args)...); +#if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(12, 0) +#pragma GCC diagnostic pop +#endif } // @@ -197,7 +205,7 @@ union TypeErasedState { template <class T> T& ObjectInLocalStorage(TypeErasedState* const state) { // We launder here because the storage may be reused with the same type. -#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L +#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606L return *std::launder(reinterpret_cast<T*>(&state->storage)); #elif ABSL_HAVE_BUILTIN(__builtin_launder) return *__builtin_launder(reinterpret_cast<T*>(&state->storage)); @@ -824,7 +832,7 @@ using CanAssignReferenceWrapper = TrueAlias< auto* invoker = this->invoker_; \ if (!std::is_const<QualifiedTestType>::value && \ std::is_rvalue_reference<QualifiedTestType>::value) { \ - ABSL_HARDENING_ASSERT([this]() { \ + ABSL_ASSERT([this]() { \ /* We checked that this isn't const above, so const_cast is safe */ \ const_cast<Impl*>(this)->invoker_ = InvokedAfterMove; \ return this->HasValue(); \ diff --git a/absl/hash/BUILD.bazel b/absl/hash/BUILD.bazel index a0db919b..7f964ae7 100644 --- a/absl/hash/BUILD.bazel +++ b/absl/hash/BUILD.bazel @@ -68,13 +68,17 @@ cc_library( cc_test( name = "hash_test", - srcs = ["hash_test.cc"], + srcs = [ + "hash_test.cc", + "internal/hash_test.h", + ], copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":hash", ":hash_testing", ":spy_hash_state", + "//absl/base:config", "//absl/base:core_headers", "//absl/container:btree", "//absl/container:flat_hash_map", @@ -88,6 +92,27 @@ cc_test( ], ) +cc_test( + name = "hash_instantiated_test", + srcs = [ + "hash_instantiated_test.cc", + "internal/hash_test.h", + ], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":hash", + ":hash_testing", + "//absl/base:config", + "//absl/container:btree", + "//absl/container:flat_hash_map", + "//absl/container:flat_hash_set", + "//absl/container:node_hash_map", + "//absl/container:node_hash_set", + "@com_google_googletest//:gtest_main", + ], +) + cc_binary( name = "hash_benchmark", testonly = 1, diff --git a/absl/hash/CMakeLists.txt b/absl/hash/CMakeLists.txt index f99f35bc..1adce617 100644 --- a/absl/hash/CMakeLists.txt +++ b/absl/hash/CMakeLists.txt @@ -64,6 +64,7 @@ absl_cc_test( hash_test SRCS "hash_test.cc" + "internal/hash_test.h" COPTS ${ABSL_TEST_COPTS} DEPS @@ -82,6 +83,26 @@ absl_cc_test( GTest::gmock_main ) +absl_cc_test( + NAME + hash_instantiated_test + SRCS + "hash_test.cc" + "internal/hash_test.h" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::hash + absl::hash_testing + absl::config + absl::btree + absl::flat_hash_map + absl::flat_hash_set + absl::node_hash_map + absl::node_hash_set + GTest::gtest_main +) + # Internal-only target, do not depend on directly. # # Note: Even though external code should not depend on this target diff --git a/absl/hash/hash_instantiated_test.cc b/absl/hash/hash_instantiated_test.cc new file mode 100644 index 00000000..e65de9ca --- /dev/null +++ b/absl/hash/hash_instantiated_test.cc @@ -0,0 +1,224 @@ +// Copyright 2018 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains a few select absl::Hash tests that, due to their reliance +// on INSTANTIATE_TYPED_TEST_SUITE_P, require a large amount of memory to +// compile. Put new tests in hash_test.cc, not this file. + +#include "absl/hash/hash.h" + +#include <stddef.h> + +#include <algorithm> +#include <deque> +#include <forward_list> +#include <initializer_list> +#include <list> +#include <map> +#include <set> +#include <string> +#include <type_traits> +#include <unordered_map> +#include <unordered_set> +#include <utility> +#include <vector> + +#include "gtest/gtest.h" +#include "absl/container/btree_map.h" +#include "absl/container/btree_set.h" +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/container/node_hash_map.h" +#include "absl/container/node_hash_set.h" +#include "absl/hash/hash_testing.h" +#include "absl/hash/internal/hash_test.h" + +namespace { + +using ::absl::hash_test_internal::is_hashable; +using ::absl::hash_test_internal::TypeErasedContainer; + +// Dummy type with unordered equality and hashing semantics. This preserves +// input order internally, and is used below to ensure we get test coverage +// for equal sequences with different iteraton orders. +template <typename T> +class UnorderedSequence { + public: + UnorderedSequence() = default; + template <typename TT> + UnorderedSequence(std::initializer_list<TT> l) + : values_(l.begin(), l.end()) {} + template <typename ForwardIterator, + typename std::enable_if<!std::is_integral<ForwardIterator>::value, + bool>::type = true> + UnorderedSequence(ForwardIterator begin, ForwardIterator end) + : values_(begin, end) {} + // one-argument constructor of value type T, to appease older toolchains that + // get confused by one-element initializer lists in some contexts + explicit UnorderedSequence(const T& v) : values_(&v, &v + 1) {} + + using value_type = T; + + size_t size() const { return values_.size(); } + typename std::vector<T>::const_iterator begin() const { + return values_.begin(); + } + typename std::vector<T>::const_iterator end() const { return values_.end(); } + + friend bool operator==(const UnorderedSequence& lhs, + const UnorderedSequence& rhs) { + return lhs.size() == rhs.size() && + std::is_permutation(lhs.begin(), lhs.end(), rhs.begin()); + } + friend bool operator!=(const UnorderedSequence& lhs, + const UnorderedSequence& rhs) { + return !(lhs == rhs); + } + template <typename H> + friend H AbslHashValue(H h, const UnorderedSequence& u) { + return H::combine(H::combine_unordered(std::move(h), u.begin(), u.end()), + u.size()); + } + + private: + std::vector<T> values_; +}; + +template <typename T> +class HashValueSequenceTest : public testing::Test {}; +TYPED_TEST_SUITE_P(HashValueSequenceTest); + +TYPED_TEST_P(HashValueSequenceTest, BasicUsage) { + EXPECT_TRUE((is_hashable<TypeParam>::value)); + + using IntType = typename TypeParam::value_type; + auto a = static_cast<IntType>(0); + auto b = static_cast<IntType>(23); + auto c = static_cast<IntType>(42); + + std::vector<TypeParam> exemplars = { + TypeParam(), TypeParam(), TypeParam{a, b, c}, + TypeParam{a, c, b}, TypeParam{c, a, b}, TypeParam{a}, + TypeParam{a, a}, TypeParam{a, a, a}, TypeParam{a, a, b}, + TypeParam{a, b, a}, TypeParam{b, a, a}, TypeParam{a, b}, + TypeParam{b, c}}; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); +} + +REGISTER_TYPED_TEST_SUITE_P(HashValueSequenceTest, BasicUsage); +using IntSequenceTypes = testing::Types< + std::deque<int>, std::forward_list<int>, std::list<int>, std::vector<int>, + std::vector<bool>, TypeErasedContainer<std::vector<int>>, std::set<int>, + std::multiset<int>, UnorderedSequence<int>, + TypeErasedContainer<UnorderedSequence<int>>, std::unordered_set<int>, + std::unordered_multiset<int>, absl::flat_hash_set<int>, + absl::node_hash_set<int>, absl::btree_set<int>>; +INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueSequenceTest, IntSequenceTypes); + +template <typename T> +class HashValueNestedSequenceTest : public testing::Test {}; +TYPED_TEST_SUITE_P(HashValueNestedSequenceTest); + +TYPED_TEST_P(HashValueNestedSequenceTest, BasicUsage) { + using T = TypeParam; + using V = typename T::value_type; + std::vector<T> exemplars = { + // empty case + T{}, + // sets of empty sets + T{V{}}, T{V{}, V{}}, T{V{}, V{}, V{}}, + // multisets of different values + T{V{1}}, T{V{1, 1}, V{1, 1}}, T{V{1, 1, 1}, V{1, 1, 1}, V{1, 1, 1}}, + // various orderings of same nested sets + T{V{}, V{1, 2}}, T{V{}, V{2, 1}}, T{V{1, 2}, V{}}, T{V{2, 1}, V{}}, + // various orderings of various nested sets, case 2 + T{V{1, 2}, V{3, 4}}, T{V{1, 2}, V{4, 3}}, T{V{1, 3}, V{2, 4}}, + T{V{1, 3}, V{4, 2}}, T{V{1, 4}, V{2, 3}}, T{V{1, 4}, V{3, 2}}, + T{V{2, 3}, V{1, 4}}, T{V{2, 3}, V{4, 1}}, T{V{2, 4}, V{1, 3}}, + T{V{2, 4}, V{3, 1}}, T{V{3, 4}, V{1, 2}}, T{V{3, 4}, V{2, 1}}}; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); +} + +REGISTER_TYPED_TEST_SUITE_P(HashValueNestedSequenceTest, BasicUsage); +template <typename T> +using TypeErasedSet = TypeErasedContainer<UnorderedSequence<T>>; + +using NestedIntSequenceTypes = testing::Types< + std::vector<std::vector<int>>, std::vector<UnorderedSequence<int>>, + std::vector<TypeErasedSet<int>>, UnorderedSequence<std::vector<int>>, + UnorderedSequence<UnorderedSequence<int>>, + UnorderedSequence<TypeErasedSet<int>>, TypeErasedSet<std::vector<int>>, + TypeErasedSet<UnorderedSequence<int>>, TypeErasedSet<TypeErasedSet<int>>>; +INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueNestedSequenceTest, + NestedIntSequenceTypes); + +template <typename T> +class HashValueAssociativeMapTest : public testing::Test {}; +TYPED_TEST_SUITE_P(HashValueAssociativeMapTest); + +TYPED_TEST_P(HashValueAssociativeMapTest, BasicUsage) { + using M = TypeParam; + using V = typename M::value_type; + std::vector<M> exemplars{M{}, + M{V{0, "foo"}}, + M{V{1, "foo"}}, + M{V{0, "bar"}}, + M{V{1, "bar"}}, + M{V{0, "foo"}, V{42, "bar"}}, + M{V{42, "bar"}, V{0, "foo"}}, + M{V{1, "foo"}, V{42, "bar"}}, + M{V{1, "foo"}, V{43, "bar"}}, + M{V{1, "foo"}, V{43, "baz"}}}; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); +} + +REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMapTest, BasicUsage); +using AssociativeMapTypes = testing::Types< + std::map<int, std::string>, std::unordered_map<int, std::string>, + absl::flat_hash_map<int, std::string>, + absl::node_hash_map<int, std::string>, absl::btree_map<int, std::string>, + UnorderedSequence<std::pair<const int, std::string>>>; +INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMapTest, + AssociativeMapTypes); + +template <typename T> +class HashValueAssociativeMultimapTest : public testing::Test {}; +TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest); + +TYPED_TEST_P(HashValueAssociativeMultimapTest, BasicUsage) { + using MM = TypeParam; + using V = typename MM::value_type; + std::vector<MM> exemplars{MM{}, + MM{V{0, "foo"}}, + MM{V{1, "foo"}}, + MM{V{0, "bar"}}, + MM{V{1, "bar"}}, + MM{V{0, "foo"}, V{0, "bar"}}, + MM{V{0, "bar"}, V{0, "foo"}}, + MM{V{0, "foo"}, V{42, "bar"}}, + MM{V{1, "foo"}, V{42, "bar"}}, + MM{V{1, "foo"}, V{1, "foo"}, V{43, "bar"}}, + MM{V{1, "foo"}, V{43, "bar"}, V{1, "foo"}}, + MM{V{1, "foo"}, V{43, "baz"}}}; + EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); +} + +REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest, BasicUsage); +using AssociativeMultimapTypes = + testing::Types<std::multimap<int, std::string>, + std::unordered_multimap<int, std::string>>; +INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMultimapTest, + AssociativeMultimapTypes); + +} // namespace diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index 6727dafa..a0e2e4a7 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc @@ -48,6 +48,7 @@ #include "absl/container/node_hash_map.h" #include "absl/container/node_hash_set.h" #include "absl/hash/hash_testing.h" +#include "absl/hash/internal/hash_test.h" #include "absl/hash/internal/spy_hash_state.h" #include "absl/meta/type_traits.h" #include "absl/numeric/int128.h" @@ -59,52 +60,9 @@ namespace { -// Utility wrapper of T for the purposes of testing the `AbslHash` type erasure -// mechanism. `TypeErasedValue<T>` can be constructed with a `T`, and can -// be compared and hashed. However, all hashing goes through the hashing -// type-erasure framework. -template <typename T> -class TypeErasedValue { - public: - TypeErasedValue() = default; - TypeErasedValue(const TypeErasedValue&) = default; - TypeErasedValue(TypeErasedValue&&) = default; - explicit TypeErasedValue(const T& n) : n_(n) {} - - template <typename H> - friend H AbslHashValue(H hash_state, const TypeErasedValue& v) { - v.HashValue(absl::HashState::Create(&hash_state)); - return hash_state; - } - - void HashValue(absl::HashState state) const { - absl::HashState::combine(std::move(state), n_); - } - - bool operator==(const TypeErasedValue& rhs) const { return n_ == rhs.n_; } - bool operator!=(const TypeErasedValue& rhs) const { return !(*this == rhs); } - - private: - T n_; -}; - -// A TypeErasedValue refinement, for containers. It exposes the wrapped -// `value_type` and is constructible from an initializer list. -template <typename T> -class TypeErasedContainer : public TypeErasedValue<T> { - public: - using value_type = typename T::value_type; - TypeErasedContainer() = default; - TypeErasedContainer(const TypeErasedContainer&) = default; - TypeErasedContainer(TypeErasedContainer&&) = default; - explicit TypeErasedContainer(const T& n) : TypeErasedValue<T>(n) {} - TypeErasedContainer(std::initializer_list<value_type> init_list) - : TypeErasedContainer(T(init_list.begin(), init_list.end())) {} - // one-argument constructor of value type T, to appease older toolchains that - // get confused by one-element initializer lists in some contexts - explicit TypeErasedContainer(const value_type& v) - : TypeErasedContainer(T(&v, &v + 1)) {} -}; +using ::absl::hash_test_internal::is_hashable; +using ::absl::hash_test_internal::TypeErasedContainer; +using ::absl::hash_test_internal::TypeErasedValue; template <typename T> using TypeErasedVector = TypeErasedContainer<std::vector<T>>; @@ -122,11 +80,6 @@ SpyHashState SpyHash(const T& value) { return SpyHashState::combine(SpyHashState(), value); } -// Helper trait to verify if T is hashable. We use absl::Hash's poison status to -// detect it. -template <typename T> -using is_hashable = std::is_default_constructible<absl::Hash<T>>; - TYPED_TEST_P(HashValueIntTest, BasicUsage) { EXPECT_TRUE((is_hashable<TypeParam>::value)); @@ -566,121 +519,6 @@ TEST(HashValueTest, StdBitset) { std::bitset<kNumBits>(bit_strings[5].c_str())})); } // namespace -// Dummy type with unordered equality and hashing semantics. This preserves -// input order internally, and is used below to ensure we get test coverage -// for equal sequences with different iteraton orders. -template <typename T> -class UnorderedSequence { - public: - UnorderedSequence() = default; - template <typename TT> - UnorderedSequence(std::initializer_list<TT> l) - : values_(l.begin(), l.end()) {} - template <typename ForwardIterator, - typename std::enable_if<!std::is_integral<ForwardIterator>::value, - bool>::type = true> - UnorderedSequence(ForwardIterator begin, ForwardIterator end) - : values_(begin, end) {} - // one-argument constructor of value type T, to appease older toolchains that - // get confused by one-element initializer lists in some contexts - explicit UnorderedSequence(const T& v) : values_(&v, &v + 1) {} - - using value_type = T; - - size_t size() const { return values_.size(); } - typename std::vector<T>::const_iterator begin() const { - return values_.begin(); - } - typename std::vector<T>::const_iterator end() const { return values_.end(); } - - friend bool operator==(const UnorderedSequence& lhs, - const UnorderedSequence& rhs) { - return lhs.size() == rhs.size() && - std::is_permutation(lhs.begin(), lhs.end(), rhs.begin()); - } - friend bool operator!=(const UnorderedSequence& lhs, - const UnorderedSequence& rhs) { - return !(lhs == rhs); - } - template <typename H> - friend H AbslHashValue(H h, const UnorderedSequence& u) { - return H::combine(H::combine_unordered(std::move(h), u.begin(), u.end()), - u.size()); - } - - private: - std::vector<T> values_; -}; - -template <typename T> -class HashValueSequenceTest : public testing::Test { -}; -TYPED_TEST_SUITE_P(HashValueSequenceTest); - -TYPED_TEST_P(HashValueSequenceTest, BasicUsage) { - EXPECT_TRUE((is_hashable<TypeParam>::value)); - - using IntType = typename TypeParam::value_type; - auto a = static_cast<IntType>(0); - auto b = static_cast<IntType>(23); - auto c = static_cast<IntType>(42); - - std::vector<TypeParam> exemplars = { - TypeParam(), TypeParam(), TypeParam{a, b, c}, - TypeParam{a, c, b}, TypeParam{c, a, b}, TypeParam{a}, - TypeParam{a, a}, TypeParam{a, a, a}, TypeParam{a, a, b}, - TypeParam{a, b, a}, TypeParam{b, a, a}, TypeParam{a, b}, - TypeParam{b, c}}; - EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -} - -REGISTER_TYPED_TEST_SUITE_P(HashValueSequenceTest, BasicUsage); -using IntSequenceTypes = testing::Types< - std::deque<int>, std::forward_list<int>, std::list<int>, std::vector<int>, - std::vector<bool>, TypeErasedContainer<std::vector<int>>, std::set<int>, - std::multiset<int>, UnorderedSequence<int>, - TypeErasedContainer<UnorderedSequence<int>>, std::unordered_set<int>, - std::unordered_multiset<int>, absl::flat_hash_set<int>, - absl::node_hash_set<int>, absl::btree_set<int>>; -INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueSequenceTest, IntSequenceTypes); - -template <typename T> -class HashValueNestedSequenceTest : public testing::Test {}; -TYPED_TEST_SUITE_P(HashValueNestedSequenceTest); - -TYPED_TEST_P(HashValueNestedSequenceTest, BasicUsage) { - using T = TypeParam; - using V = typename T::value_type; - std::vector<T> exemplars = { - // empty case - T{}, - // sets of empty sets - T{V{}}, T{V{}, V{}}, T{V{}, V{}, V{}}, - // multisets of different values - T{V{1}}, T{V{1, 1}, V{1, 1}}, T{V{1, 1, 1}, V{1, 1, 1}, V{1, 1, 1}}, - // various orderings of same nested sets - T{V{}, V{1, 2}}, T{V{}, V{2, 1}}, T{V{1, 2}, V{}}, T{V{2, 1}, V{}}, - // various orderings of various nested sets, case 2 - T{V{1, 2}, V{3, 4}}, T{V{1, 2}, V{4, 3}}, T{V{1, 3}, V{2, 4}}, - T{V{1, 3}, V{4, 2}}, T{V{1, 4}, V{2, 3}}, T{V{1, 4}, V{3, 2}}, - T{V{2, 3}, V{1, 4}}, T{V{2, 3}, V{4, 1}}, T{V{2, 4}, V{1, 3}}, - T{V{2, 4}, V{3, 1}}, T{V{3, 4}, V{1, 2}}, T{V{3, 4}, V{2, 1}}}; - EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -} - -REGISTER_TYPED_TEST_SUITE_P(HashValueNestedSequenceTest, BasicUsage); -template <typename T> -using TypeErasedSet = TypeErasedContainer<UnorderedSequence<T>>; - -using NestedIntSequenceTypes = testing::Types< - std::vector<std::vector<int>>, std::vector<UnorderedSequence<int>>, - std::vector<TypeErasedSet<int>>, UnorderedSequence<std::vector<int>>, - UnorderedSequence<UnorderedSequence<int>>, - UnorderedSequence<TypeErasedSet<int>>, TypeErasedSet<std::vector<int>>, - TypeErasedSet<UnorderedSequence<int>>, TypeErasedSet<TypeErasedSet<int>>>; -INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueNestedSequenceTest, - NestedIntSequenceTypes); - // Private type that only supports AbslHashValue to make sure our chosen hash // implementation is recursive within absl::Hash. // It uses std::abs() on the value to provide different bitwise representations @@ -839,64 +677,6 @@ TEST(HashValueTest, Variant) { #endif } -template <typename T> -class HashValueAssociativeMapTest : public testing::Test {}; -TYPED_TEST_SUITE_P(HashValueAssociativeMapTest); - -TYPED_TEST_P(HashValueAssociativeMapTest, BasicUsage) { - using M = TypeParam; - using V = typename M::value_type; - std::vector<M> exemplars{M{}, - M{V{0, "foo"}}, - M{V{1, "foo"}}, - M{V{0, "bar"}}, - M{V{1, "bar"}}, - M{V{0, "foo"}, V{42, "bar"}}, - M{V{42, "bar"}, V{0, "foo"}}, - M{V{1, "foo"}, V{42, "bar"}}, - M{V{1, "foo"}, V{43, "bar"}}, - M{V{1, "foo"}, V{43, "baz"}}}; - EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -} - -REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMapTest, BasicUsage); -using AssociativeMapTypes = testing::Types< - std::map<int, std::string>, std::unordered_map<int, std::string>, - absl::flat_hash_map<int, std::string>, - absl::node_hash_map<int, std::string>, absl::btree_map<int, std::string>, - UnorderedSequence<std::pair<const int, std::string>>>; -INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMapTest, - AssociativeMapTypes); - -template <typename T> -class HashValueAssociativeMultimapTest : public testing::Test {}; -TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest); - -TYPED_TEST_P(HashValueAssociativeMultimapTest, BasicUsage) { - using MM = TypeParam; - using V = typename MM::value_type; - std::vector<MM> exemplars{MM{}, - MM{V{0, "foo"}}, - MM{V{1, "foo"}}, - MM{V{0, "bar"}}, - MM{V{1, "bar"}}, - MM{V{0, "foo"}, V{0, "bar"}}, - MM{V{0, "bar"}, V{0, "foo"}}, - MM{V{0, "foo"}, V{42, "bar"}}, - MM{V{1, "foo"}, V{42, "bar"}}, - MM{V{1, "foo"}, V{1, "foo"}, V{43, "bar"}}, - MM{V{1, "foo"}, V{43, "bar"}, V{1, "foo"}}, - MM{V{1, "foo"}, V{43, "baz"}}}; - EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(exemplars)); -} - -REGISTER_TYPED_TEST_SUITE_P(HashValueAssociativeMultimapTest, BasicUsage); -using AssociativeMultimapTypes = - testing::Types<std::multimap<int, std::string>, - std::unordered_multimap<int, std::string>>; -INSTANTIATE_TYPED_TEST_SUITE_P(My, HashValueAssociativeMultimapTest, - AssociativeMultimapTypes); - TEST(HashValueTest, ReferenceWrapper) { EXPECT_TRUE(is_hashable<std::reference_wrapper<Private>>::value); diff --git a/absl/hash/internal/hash_test.h b/absl/hash/internal/hash_test.h new file mode 100644 index 00000000..9963dc0b --- /dev/null +++ b/absl/hash/internal/hash_test.h @@ -0,0 +1,87 @@ +// Copyright 2023 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Common code shared between absl/hash/hash_test.cc and +// absl/hash/hash_instantiated_test.cc. + +#ifndef ABSL_HASH_INTERNAL_HASH_TEST_H_ +#define ABSL_HASH_INTERNAL_HASH_TEST_H_ + +#include <type_traits> +#include <utility> + +#include "absl/base/config.h" +#include "absl/hash/hash.h" + +namespace absl { +ABSL_NAMESPACE_BEGIN +namespace hash_test_internal { + +// Utility wrapper of T for the purposes of testing the `AbslHash` type erasure +// mechanism. `TypeErasedValue<T>` can be constructed with a `T`, and can +// be compared and hashed. However, all hashing goes through the hashing +// type-erasure framework. +template <typename T> +class TypeErasedValue { + public: + TypeErasedValue() = default; + TypeErasedValue(const TypeErasedValue&) = default; + TypeErasedValue(TypeErasedValue&&) = default; + explicit TypeErasedValue(const T& n) : n_(n) {} + + template <typename H> + friend H AbslHashValue(H hash_state, const TypeErasedValue& v) { + v.HashValue(absl::HashState::Create(&hash_state)); + return hash_state; + } + + void HashValue(absl::HashState state) const { + absl::HashState::combine(std::move(state), n_); + } + + bool operator==(const TypeErasedValue& rhs) const { return n_ == rhs.n_; } + bool operator!=(const TypeErasedValue& rhs) const { return !(*this == rhs); } + + private: + T n_; +}; + +// A TypeErasedValue refinement, for containers. It exposes the wrapped +// `value_type` and is constructible from an initializer list. +template <typename T> +class TypeErasedContainer : public TypeErasedValue<T> { + public: + using value_type = typename T::value_type; + TypeErasedContainer() = default; + TypeErasedContainer(const TypeErasedContainer&) = default; + TypeErasedContainer(TypeErasedContainer&&) = default; + explicit TypeErasedContainer(const T& n) : TypeErasedValue<T>(n) {} + TypeErasedContainer(std::initializer_list<value_type> init_list) + : TypeErasedContainer(T(init_list.begin(), init_list.end())) {} + // one-argument constructor of value type T, to appease older toolchains that + // get confused by one-element initializer lists in some contexts + explicit TypeErasedContainer(const value_type& v) + : TypeErasedContainer(T(&v, &v + 1)) {} +}; + +// Helper trait to verify if T is hashable. We use absl::Hash's poison status to +// detect it. +template <typename T> +using is_hashable = std::is_default_constructible<absl::Hash<T>>; + +} // namespace hash_test_internal +ABSL_NAMESPACE_END +} // namespace absl + +#endif // ABSL_HASH_INTERNAL_HASH_TEST_H_ diff --git a/absl/log/BUILD.bazel b/absl/log/BUILD.bazel index 4813111f..e1410637 100644 --- a/absl/log/BUILD.bazel +++ b/absl/log/BUILD.bazel @@ -289,7 +289,7 @@ cc_library( "no_test_ios", "no_test_wasm", ], - textual_hdrs = ["check_test_impl.h"], + textual_hdrs = ["check_test_impl.inc"], visibility = ["//visibility:private"], deps = [ "//absl/base:config", @@ -373,7 +373,7 @@ cc_library( testonly = True, copts = ABSL_TEST_COPTS, linkopts = ABSL_DEFAULT_LINKOPTS, - textual_hdrs = ["log_basic_test_impl.h"], + textual_hdrs = ["log_basic_test_impl.inc"], visibility = ["//visibility:private"], deps = [ "//absl/base", @@ -459,7 +459,6 @@ cc_test( ":log_sink_registry", ":scoped_mock_log", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", "//absl/log/internal:test_actions", "//absl/log/internal:test_helpers", "//absl/log/internal:test_matchers", diff --git a/absl/log/CMakeLists.txt b/absl/log/CMakeLists.txt index 4cba0082..9320ce59 100644 --- a/absl/log/CMakeLists.txt +++ b/absl/log/CMakeLists.txt @@ -1,4 +1,3 @@ -# # Copyright 2022 The Abseil Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -679,7 +678,7 @@ absl_cc_test( absl_check_test SRCS "absl_check_test.cc" - "check_test_impl.h" + "check_test_impl.inc" COPTS ${ABSL_TEST_COPTS} LINKOPTS @@ -699,7 +698,7 @@ absl_cc_test( absl_log_basic_test SRCS "log_basic_test.cc" - "log_basic_test_impl.h" + "log_basic_test_impl.inc" COPTS ${ABSL_TEST_COPTS} LINKOPTS @@ -723,7 +722,7 @@ absl_cc_test( check_test SRCS "check_test.cc" - "check_test_impl.h" + "check_test_impl.inc" COPTS ${ABSL_TEST_COPTS} LINKOPTS @@ -759,7 +758,7 @@ absl_cc_test( log_basic_test SRCS "log_basic_test.cc" - "log_basic_test_impl.h" + "log_basic_test_impl.inc" COPTS ${ABSL_TEST_COPTS} LINKOPTS @@ -906,7 +905,6 @@ absl_cc_test( absl::log_sink absl::log_sink_registry absl::log_severity - absl::raw_logging_internal absl::scoped_mock_log absl::strings GTest::gtest_main diff --git a/absl/log/absl_check.h b/absl/log/absl_check.h index 14a2307f..1bb43bd3 100644 --- a/absl/log/absl_check.h +++ b/absl/log/absl_check.h @@ -37,69 +37,81 @@ #include "absl/log/internal/check_impl.h" -#define ABSL_CHECK(condition) ABSL_CHECK_IMPL((condition), #condition) -#define ABSL_QCHECK(condition) ABSL_QCHECK_IMPL((condition), #condition) -#define ABSL_PCHECK(condition) ABSL_PCHECK_IMPL((condition), #condition) -#define ABSL_DCHECK(condition) ABSL_DCHECK_IMPL((condition), #condition) +#define ABSL_CHECK(condition) \ + ABSL_LOG_INTERNAL_CHECK_IMPL((condition), #condition) +#define ABSL_QCHECK(condition) \ + ABSL_LOG_INTERNAL_QCHECK_IMPL((condition), #condition) +#define ABSL_PCHECK(condition) \ + ABSL_LOG_INTERNAL_PCHECK_IMPL((condition), #condition) +#define ABSL_DCHECK(condition) \ + ABSL_LOG_INTERNAL_DCHECK_IMPL((condition), #condition) #define ABSL_CHECK_EQ(val1, val2) \ - ABSL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2) #define ABSL_CHECK_NE(val1, val2) \ - ABSL_CHECK_NE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_CHECK_NE_IMPL((val1), #val1, (val2), #val2) #define ABSL_CHECK_LE(val1, val2) \ - ABSL_CHECK_LE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_CHECK_LE_IMPL((val1), #val1, (val2), #val2) #define ABSL_CHECK_LT(val1, val2) \ - ABSL_CHECK_LT_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_CHECK_LT_IMPL((val1), #val1, (val2), #val2) #define ABSL_CHECK_GE(val1, val2) \ - ABSL_CHECK_GE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_CHECK_GE_IMPL((val1), #val1, (val2), #val2) #define ABSL_CHECK_GT(val1, val2) \ - ABSL_CHECK_GT_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_CHECK_GT_IMPL((val1), #val1, (val2), #val2) #define ABSL_QCHECK_EQ(val1, val2) \ - ABSL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2) #define ABSL_QCHECK_NE(val1, val2) \ - ABSL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2) #define ABSL_QCHECK_LE(val1, val2) \ - ABSL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2) #define ABSL_QCHECK_LT(val1, val2) \ - ABSL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2) #define ABSL_QCHECK_GE(val1, val2) \ - ABSL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2) #define ABSL_QCHECK_GT(val1, val2) \ - ABSL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2) #define ABSL_DCHECK_EQ(val1, val2) \ - ABSL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2) #define ABSL_DCHECK_NE(val1, val2) \ - ABSL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2) #define ABSL_DCHECK_LE(val1, val2) \ - ABSL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2) #define ABSL_DCHECK_LT(val1, val2) \ - ABSL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2) #define ABSL_DCHECK_GE(val1, val2) \ - ABSL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2) #define ABSL_DCHECK_GT(val1, val2) \ - ABSL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2) + ABSL_LOG_INTERNAL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2) -#define ABSL_CHECK_OK(status) ABSL_CHECK_OK_IMPL((status), #status) -#define ABSL_QCHECK_OK(status) ABSL_QCHECK_OK_IMPL((status), #status) -#define ABSL_DCHECK_OK(status) ABSL_DCHECK_OK_IMPL((status), #status) +#define ABSL_CHECK_OK(status) ABSL_LOG_INTERNAL_CHECK_OK_IMPL((status), #status) +#define ABSL_QCHECK_OK(status) \ + ABSL_LOG_INTERNAL_QCHECK_OK_IMPL((status), #status) +#define ABSL_DCHECK_OK(status) \ + ABSL_LOG_INTERNAL_DCHECK_OK_IMPL((status), #status) -#define ABSL_CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2) -#define ABSL_CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_CHECK_STREQ(s1, s2) \ + ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_CHECK_STRNE(s1, s2) \ + ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2) #define ABSL_CHECK_STRCASEEQ(s1, s2) \ - ABSL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) #define ABSL_CHECK_STRCASENE(s1, s2) \ - ABSL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) -#define ABSL_QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) -#define ABSL_QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_QCHECK_STREQ(s1, s2) \ + ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_QCHECK_STRNE(s1, s2) \ + ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) #define ABSL_QCHECK_STRCASEEQ(s1, s2) \ - ABSL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) #define ABSL_QCHECK_STRCASENE(s1, s2) \ - ABSL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) -#define ABSL_DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) -#define ABSL_DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define ABSL_DCHECK_STREQ(s1, s2) \ + ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define ABSL_DCHECK_STRNE(s1, s2) \ + ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) #define ABSL_DCHECK_STRCASEEQ(s1, s2) \ - ABSL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) #define ABSL_DCHECK_STRCASENE(s1, s2) \ - ABSL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) #endif // ABSL_LOG_ABSL_CHECK_H_ diff --git a/absl/log/absl_check_test.cc b/absl/log/absl_check_test.cc index 8ddacdb1..d84940fa 100644 --- a/absl/log/absl_check_test.cc +++ b/absl/log/absl_check_test.cc @@ -55,4 +55,4 @@ #define ABSL_TEST_QCHECK_STRCASENE ABSL_QCHECK_STRCASENE #include "gtest/gtest.h" -#include "absl/log/check_test_impl.h" +#include "absl/log/check_test_impl.inc" diff --git a/absl/log/absl_log.h b/absl/log/absl_log.h index 1c6cf263..0517760b 100644 --- a/absl/log/absl_log.h +++ b/absl/log/absl_log.h @@ -35,60 +35,69 @@ #include "absl/log/internal/log_impl.h" -#define ABSL_LOG(severity) ABSL_LOG_IMPL(_##severity) -#define ABSL_PLOG(severity) ABSL_PLOG_IMPL(_##severity) -#define ABSL_DLOG(severity) ABSL_DLOG_IMPL(_##severity) +#define ABSL_LOG(severity) ABSL_LOG_INTERNAL_LOG_IMPL(_##severity) +#define ABSL_PLOG(severity) ABSL_LOG_INTERNAL_PLOG_IMPL(_##severity) +#define ABSL_DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity) #define ABSL_LOG_IF(severity, condition) \ - ABSL_LOG_IF_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition) #define ABSL_PLOG_IF(severity, condition) \ - ABSL_PLOG_IF_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_PLOG_IF_IMPL(_##severity, condition) #define ABSL_DLOG_IF(severity, condition) \ - ABSL_DLOG_IF_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_DLOG_IF_IMPL(_##severity, condition) -#define ABSL_LOG_EVERY_N(severity, n) ABSL_LOG_EVERY_N_IMPL(_##severity, n) -#define ABSL_LOG_FIRST_N(severity, n) ABSL_LOG_FIRST_N_IMPL(_##severity, n) -#define ABSL_LOG_EVERY_POW_2(severity) ABSL_LOG_EVERY_POW_2_IMPL(_##severity) +#define ABSL_LOG_EVERY_N(severity, n) \ + ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n) +#define ABSL_LOG_FIRST_N(severity, n) \ + ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n) +#define ABSL_LOG_EVERY_POW_2(severity) \ + ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity) #define ABSL_LOG_EVERY_N_SEC(severity, n_seconds) \ - ABSL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) + ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) -#define ABSL_PLOG_EVERY_N(severity, n) ABSL_PLOG_EVERY_N_IMPL(_##severity, n) -#define ABSL_PLOG_FIRST_N(severity, n) ABSL_PLOG_FIRST_N_IMPL(_##severity, n) -#define ABSL_PLOG_EVERY_POW_2(severity) ABSL_PLOG_EVERY_POW_2_IMPL(_##severity) +#define ABSL_PLOG_EVERY_N(severity, n) \ + ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(_##severity, n) +#define ABSL_PLOG_FIRST_N(severity, n) \ + ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(_##severity, n) +#define ABSL_PLOG_EVERY_POW_2(severity) \ + ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(_##severity) #define ABSL_PLOG_EVERY_N_SEC(severity, n_seconds) \ - ABSL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) + ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) -#define ABSL_DLOG_EVERY_N(severity, n) ABSL_DLOG_EVERY_N_IMPL(_##severity, n) -#define ABSL_DLOG_FIRST_N(severity, n) ABSL_DLOG_FIRST_N_IMPL(_##severity, n) -#define ABSL_DLOG_EVERY_POW_2(severity) ABSL_DLOG_EVERY_POW_2_IMPL(_##severity) +#define ABSL_DLOG_EVERY_N(severity, n) \ + ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(_##severity, n) +#define ABSL_DLOG_FIRST_N(severity, n) \ + ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(_##severity, n) +#define ABSL_DLOG_EVERY_POW_2(severity) \ + ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(_##severity) #define ABSL_DLOG_EVERY_N_SEC(severity, n_seconds) \ - ABSL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) + ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) #define ABSL_LOG_IF_EVERY_N(severity, condition, n) \ - ABSL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n) #define ABSL_LOG_IF_FIRST_N(severity, condition, n) \ - ABSL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n) #define ABSL_LOG_IF_EVERY_POW_2(severity, condition) \ - ABSL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition) #define ABSL_LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ - ABSL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) + ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) #define ABSL_PLOG_IF_EVERY_N(severity, condition, n) \ - ABSL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n) #define ABSL_PLOG_IF_FIRST_N(severity, condition, n) \ - ABSL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n) #define ABSL_PLOG_IF_EVERY_POW_2(severity, condition) \ - ABSL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) #define ABSL_PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ - ABSL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) + ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) #define ABSL_DLOG_IF_EVERY_N(severity, condition, n) \ - ABSL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n) #define ABSL_DLOG_IF_FIRST_N(severity, condition, n) \ - ABSL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n) #define ABSL_DLOG_IF_EVERY_POW_2(severity, condition) \ - ABSL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) #define ABSL_DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ - ABSL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) + ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) #endif // ABSL_LOG_ABSL_LOG_H_ diff --git a/absl/log/absl_log_basic_test.cc b/absl/log/absl_log_basic_test.cc index bc8a787d..3a4b83c1 100644 --- a/absl/log/absl_log_basic_test.cc +++ b/absl/log/absl_log_basic_test.cc @@ -18,4 +18,4 @@ #define ABSL_TEST_LOG ABSL_LOG #include "gtest/gtest.h" -#include "absl/log/log_basic_test_impl.h" +#include "absl/log/log_basic_test_impl.inc" diff --git a/absl/log/check.h b/absl/log/check.h index 33145a57..0a2f2e4e 100644 --- a/absl/log/check.h +++ b/absl/log/check.h @@ -54,7 +54,7 @@ // Might produce a message like: // // Check failed: !cheese.empty() Out of Cheese -#define CHECK(condition) ABSL_CHECK_IMPL((condition), #condition) +#define CHECK(condition) ABSL_LOG_INTERNAL_CHECK_IMPL((condition), #condition) // QCHECK() // @@ -62,7 +62,7 @@ // not run registered error handlers (as `QFATAL`). It is useful when the // problem is definitely unrelated to program flow, e.g. when validating user // input. -#define QCHECK(condition) ABSL_QCHECK_IMPL((condition), #condition) +#define QCHECK(condition) ABSL_LOG_INTERNAL_QCHECK_IMPL((condition), #condition) // PCHECK() // @@ -77,7 +77,7 @@ // Might produce a message like: // // Check failed: fd != -1 posix is difficult: No such file or directory [2] -#define PCHECK(condition) ABSL_PCHECK_IMPL((condition), #condition) +#define PCHECK(condition) ABSL_LOG_INTERNAL_PCHECK_IMPL((condition), #condition) // DCHECK() // @@ -85,7 +85,7 @@ // `DLOG`). Unlike with `CHECK` (but as with `assert`), it is not safe to rely // on evaluation of `condition`: when `NDEBUG` is enabled, DCHECK does not // evaluate the condition. -#define DCHECK(condition) ABSL_DCHECK_IMPL((condition), #condition) +#define DCHECK(condition) ABSL_LOG_INTERNAL_DCHECK_IMPL((condition), #condition) // `CHECK_EQ` and friends are syntactic sugar for `CHECK(x == y)` that // automatically output the expression being tested and the evaluated values on @@ -113,24 +113,42 @@ // // WARNING: Passing `NULL` as an argument to `CHECK_EQ` and similar macros does // not compile. Use `nullptr` instead. -#define CHECK_EQ(val1, val2) ABSL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2) -#define CHECK_NE(val1, val2) ABSL_CHECK_NE_IMPL((val1), #val1, (val2), #val2) -#define CHECK_LE(val1, val2) ABSL_CHECK_LE_IMPL((val1), #val1, (val2), #val2) -#define CHECK_LT(val1, val2) ABSL_CHECK_LT_IMPL((val1), #val1, (val2), #val2) -#define CHECK_GE(val1, val2) ABSL_CHECK_GE_IMPL((val1), #val1, (val2), #val2) -#define CHECK_GT(val1, val2) ABSL_CHECK_GT_IMPL((val1), #val1, (val2), #val2) -#define QCHECK_EQ(val1, val2) ABSL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2) -#define QCHECK_NE(val1, val2) ABSL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2) -#define QCHECK_LE(val1, val2) ABSL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2) -#define QCHECK_LT(val1, val2) ABSL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2) -#define QCHECK_GE(val1, val2) ABSL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2) -#define QCHECK_GT(val1, val2) ABSL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2) -#define DCHECK_EQ(val1, val2) ABSL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2) -#define DCHECK_NE(val1, val2) ABSL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2) -#define DCHECK_LE(val1, val2) ABSL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2) -#define DCHECK_LT(val1, val2) ABSL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2) -#define DCHECK_GE(val1, val2) ABSL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2) -#define DCHECK_GT(val1, val2) ABSL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2) +#define CHECK_EQ(val1, val2) \ + ABSL_LOG_INTERNAL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define CHECK_NE(val1, val2) \ + ABSL_LOG_INTERNAL_CHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define CHECK_LE(val1, val2) \ + ABSL_LOG_INTERNAL_CHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define CHECK_LT(val1, val2) \ + ABSL_LOG_INTERNAL_CHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define CHECK_GE(val1, val2) \ + ABSL_LOG_INTERNAL_CHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define CHECK_GT(val1, val2) \ + ABSL_LOG_INTERNAL_CHECK_GT_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_EQ(val1, val2) \ + ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_NE(val1, val2) \ + ABSL_LOG_INTERNAL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_LE(val1, val2) \ + ABSL_LOG_INTERNAL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_LT(val1, val2) \ + ABSL_LOG_INTERNAL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_GE(val1, val2) \ + ABSL_LOG_INTERNAL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define QCHECK_GT(val1, val2) \ + ABSL_LOG_INTERNAL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_EQ(val1, val2) \ + ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_NE(val1, val2) \ + ABSL_LOG_INTERNAL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_LE(val1, val2) \ + ABSL_LOG_INTERNAL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_LT(val1, val2) \ + ABSL_LOG_INTERNAL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_GE(val1, val2) \ + ABSL_LOG_INTERNAL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2) +#define DCHECK_GT(val1, val2) \ + ABSL_LOG_INTERNAL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2) // `CHECK_OK` and friends validate that the provided `absl::Status` or // `absl::StatusOr<T>` is OK. If it isn't, they print a failure message that @@ -146,9 +164,9 @@ // Might produce a message like: // // Check failed: FunctionReturnsStatus(x, y, z) is OK (ABORTED: timeout) oops! -#define CHECK_OK(status) ABSL_CHECK_OK_IMPL((status), #status) -#define QCHECK_OK(status) ABSL_QCHECK_OK_IMPL((status), #status) -#define DCHECK_OK(status) ABSL_DCHECK_OK_IMPL((status), #status) +#define CHECK_OK(status) ABSL_LOG_INTERNAL_CHECK_OK_IMPL((status), #status) +#define QCHECK_OK(status) ABSL_LOG_INTERNAL_QCHECK_OK_IMPL((status), #status) +#define DCHECK_OK(status) ABSL_LOG_INTERNAL_DCHECK_OK_IMPL((status), #status) // `CHECK_STREQ` and friends provide `CHECK_EQ` functionality for C strings, // i.e., nul-terminated char arrays. The `CASE` versions are case-insensitive. @@ -163,21 +181,29 @@ // Example: // // CHECK_STREQ(Foo().c_str(), Bar().c_str()); -#define CHECK_STREQ(s1, s2) ABSL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2) -#define CHECK_STRNE(s1, s2) ABSL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2) -#define CHECK_STRCASEEQ(s1, s2) ABSL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) -#define CHECK_STRCASENE(s1, s2) ABSL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) -#define QCHECK_STREQ(s1, s2) ABSL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) -#define QCHECK_STRNE(s1, s2) ABSL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define CHECK_STREQ(s1, s2) \ + ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define CHECK_STRNE(s1, s2) \ + ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2) +#define CHECK_STRCASEEQ(s1, s2) \ + ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) +#define CHECK_STRCASENE(s1, s2) \ + ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define QCHECK_STREQ(s1, s2) \ + ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define QCHECK_STRNE(s1, s2) \ + ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) #define QCHECK_STRCASEEQ(s1, s2) \ - ABSL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) #define QCHECK_STRCASENE(s1, s2) \ - ABSL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) -#define DCHECK_STREQ(s1, s2) ABSL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) -#define DCHECK_STRNE(s1, s2) ABSL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) +#define DCHECK_STREQ(s1, s2) \ + ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2) +#define DCHECK_STRNE(s1, s2) \ + ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2) #define DCHECK_STRCASEEQ(s1, s2) \ - ABSL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2) #define DCHECK_STRCASENE(s1, s2) \ - ABSL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) + ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2) #endif // ABSL_LOG_CHECK_H_ diff --git a/absl/log/check_test.cc b/absl/log/check_test.cc index f44a686e..ef415bd4 100644 --- a/absl/log/check_test.cc +++ b/absl/log/check_test.cc @@ -55,4 +55,4 @@ #define ABSL_TEST_QCHECK_STRCASENE QCHECK_STRCASENE #include "gtest/gtest.h" -#include "absl/log/check_test_impl.h" +#include "absl/log/check_test_impl.inc" diff --git a/absl/log/check_test_impl.h b/absl/log/check_test_impl.inc index d5c0aee4..d5c0aee4 100644 --- a/absl/log/check_test_impl.h +++ b/absl/log/check_test_impl.inc diff --git a/absl/log/internal/check_impl.h b/absl/log/internal/check_impl.h index c9c28e3e..00f25f80 100644 --- a/absl/log/internal/check_impl.h +++ b/absl/log/internal/check_impl.h @@ -22,128 +22,128 @@ #include "absl/log/internal/strip.h" // CHECK -#define ABSL_CHECK_IMPL(condition, condition_text) \ +#define ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text) \ ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, \ ABSL_PREDICT_FALSE(!(condition))) \ ABSL_LOG_INTERNAL_CHECK(condition_text).InternalStream() -#define ABSL_QCHECK_IMPL(condition, condition_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_IMPL(condition, condition_text) \ ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, \ ABSL_PREDICT_FALSE(!(condition))) \ ABSL_LOG_INTERNAL_QCHECK(condition_text).InternalStream() -#define ABSL_PCHECK_IMPL(condition, condition_text) \ - ABSL_CHECK_IMPL(condition, condition_text).WithPerror() +#define ABSL_LOG_INTERNAL_PCHECK_IMPL(condition, condition_text) \ + ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text).WithPerror() #ifndef NDEBUG -#define ABSL_DCHECK_IMPL(condition, condition_text) \ - ABSL_CHECK_IMPL(condition, condition_text) +#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \ + ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text) #else -#define ABSL_DCHECK_IMPL(condition, condition_text) \ - ABSL_CHECK_IMPL(true || (condition), "true") +#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \ + ABSL_LOG_INTERNAL_CHECK_IMPL(true || (condition), "true") #endif // CHECK_EQ -#define ABSL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text) -#define ABSL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_CHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text) -#define ABSL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_CHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text) -#define ABSL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_CHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text) -#define ABSL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_CHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text) -#define ABSL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_CHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text) -#define ABSL_QCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_QCHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text) -#define ABSL_QCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_QCHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text) -#define ABSL_QCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_QCHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text) -#define ABSL_QCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_QCHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text) -#define ABSL_QCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_QCHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text) -#define ABSL_QCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_QCHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text) #ifndef NDEBUG -#define ABSL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ - ABSL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) -#define ABSL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ - ABSL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) -#define ABSL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ - ABSL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) -#define ABSL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ - ABSL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) -#define ABSL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ - ABSL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) -#define ABSL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ - ABSL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) +#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ + ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) #else // ndef NDEBUG -#define ABSL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) -#define ABSL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2) #endif // def NDEBUG // CHECK_OK -#define ABSL_CHECK_OK_IMPL(status, status_text) \ +#define ABSL_LOG_INTERNAL_CHECK_OK_IMPL(status, status_text) \ ABSL_LOG_INTERNAL_CHECK_OK(status, status_text) -#define ABSL_QCHECK_OK_IMPL(status, status_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_OK_IMPL(status, status_text) \ ABSL_LOG_INTERNAL_QCHECK_OK(status, status_text) #ifndef NDEBUG -#define ABSL_DCHECK_OK_IMPL(status, status_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \ ABSL_LOG_INTERNAL_CHECK_OK(status, status_text) #else -#define ABSL_DCHECK_OK_IMPL(status, status_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(status, nullptr) #endif // CHECK_STREQ -#define ABSL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text) -#define ABSL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text) -#define ABSL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text) -#define ABSL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, s2_text) -#define ABSL_QCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text) -#define ABSL_QCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text) -#define ABSL_QCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text) -#define ABSL_QCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ - ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, \ +#define ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, \ s2_text) #ifndef NDEBUG -#define ABSL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ - ABSL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) -#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ - ABSL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) -#define ABSL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ - ABSL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) -#define ABSL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ - ABSL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) +#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) +#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) +#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) +#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ + ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) #else // ndef NDEBUG -#define ABSL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) -#define ABSL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) -#define ABSL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) -#define ABSL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ +#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \ ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2) #endif // def NDEBUG diff --git a/absl/log/internal/globals.cc b/absl/log/internal/globals.cc index 863b047f..9ba997d5 100644 --- a/absl/log/internal/globals.cc +++ b/absl/log/internal/globals.cc @@ -16,6 +16,9 @@ #include <atomic> #include <cstdio> +#if defined(__EMSCRIPTEN__) +#include <emscripten/console.h> +#endif #include "absl/base/attributes.h" #include "absl/base/config.h" @@ -55,9 +58,21 @@ void SetInitialized() { } void WriteToStderr(absl::string_view message, absl::LogSeverity severity) { +#if defined(__EMSCRIPTEN__) + // In WebAssembly, bypass filesystem emulation via fwrite. + // TODO(b/282811932): Avoid this copy if these emscripten functions can + // be updated to accept size directly. + std::string null_terminated_message(message); + if (!null_terminated_message.empty() && + null_terminated_message.back() == '\n') { + null_terminated_message.pop_back(); + } + _emscripten_err(null_terminated_message.c_str()); +#else // Avoid using std::cerr from this module since we may get called during // exit code, and cerr may be partially or fully destroyed by then. std::fwrite(message.data(), message.size(), 1, stderr); +#endif #if defined(_WIN64) || defined(_WIN32) || defined(_WIN16) // C99 requires stderr to not be fully-buffered by default (7.19.3.7), but diff --git a/absl/log/internal/log_impl.h b/absl/log/internal/log_impl.h index 82b5ed84..9326780d 100644 --- a/absl/log/internal/log_impl.h +++ b/absl/log/internal/log_impl.h @@ -20,190 +20,194 @@ #include "absl/log/internal/strip.h" // ABSL_LOG() -#define ABSL_LOG_IMPL(severity) \ +#define ABSL_LOG_INTERNAL_LOG_IMPL(severity) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() // ABSL_PLOG() -#define ABSL_PLOG_IMPL(severity) \ +#define ABSL_LOG_INTERNAL_PLOG_IMPL(severity) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() // ABSL_DLOG() #ifndef NDEBUG -#define ABSL_DLOG_IMPL(severity) \ +#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() #else -#define ABSL_DLOG_IMPL(severity) \ +#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() #endif -#define ABSL_LOG_IF_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_LOG_IF_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_PLOG_IF_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_PLOG_IF_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() #ifndef NDEBUG -#define ABSL_DLOG_IF_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() #else -#define ABSL_DLOG_IF_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false && (condition)) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() #endif // ABSL_LOG_EVERY_N -#define ABSL_LOG_EVERY_N_IMPL(severity, n) \ +#define ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(severity, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() // ABSL_LOG_FIRST_N -#define ABSL_LOG_FIRST_N_IMPL(severity, n) \ +#define ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(severity, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() // ABSL_LOG_EVERY_POW_2 -#define ABSL_LOG_EVERY_POW_2_IMPL(severity) \ +#define ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(severity) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() // ABSL_LOG_EVERY_N_SEC -#define ABSL_LOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ +#define ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_PLOG_EVERY_N_IMPL(severity, n) \ +#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(severity, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() -#define ABSL_PLOG_FIRST_N_IMPL(severity, n) \ +#define ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(severity, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() -#define ABSL_PLOG_EVERY_POW_2_IMPL(severity) \ +#define ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(severity) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() -#define ABSL_PLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ +#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() #ifndef NDEBUG -#define ABSL_DLOG_EVERY_N_IMPL(severity, n) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ +#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ (EveryN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_FIRST_N_IMPL(severity, n) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ +#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ (FirstN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_EVERY_POW_2_IMPL(severity) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ +#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ (EveryPow2) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ +#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \ (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() #else // def NDEBUG -#define ABSL_DLOG_EVERY_N_IMPL(severity, n) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ +#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ (EveryN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_FIRST_N_IMPL(severity, n) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ +#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ (FirstN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_EVERY_POW_2_IMPL(severity) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ +#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ (EveryPow2) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ - ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ +#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \ + ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \ (EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() #endif // def NDEBUG -#define ABSL_LOG_IF_EVERY_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_LOG_IF_FIRST_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_LOG_IF_EVERY_POW_2_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_LOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds) \ +#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(severity, condition, \ + n_seconds) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \ n_seconds) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_PLOG_IF_EVERY_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() -#define ABSL_PLOG_IF_FIRST_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() -#define ABSL_PLOG_IF_EVERY_POW_2_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() -#define ABSL_PLOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds) \ +#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \ + n_seconds) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \ n_seconds) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \ .WithPerror() #ifndef NDEBUG -#define ABSL_DLOG_IF_EVERY_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_IF_FIRST_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \ + n_seconds) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \ n_seconds) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() #else // def NDEBUG -#define ABSL_DLOG_IF_EVERY_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \ EveryN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_IF_FIRST_N_IMPL(severity, condition, n) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \ FirstN, n) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \ EveryPow2) ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() -#define ABSL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, n_seconds) \ +#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \ + n_seconds) \ ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \ EveryNSec, n_seconds) \ ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() diff --git a/absl/log/log.h b/absl/log/log.h index e060a0b6..602b5acf 100644 --- a/absl/log/log.h +++ b/absl/log/log.h @@ -196,29 +196,32 @@ // Example: // // LOG(INFO) << "Found " << num_cookies << " cookies"; -#define LOG(severity) ABSL_LOG_IMPL(_##severity) +#define LOG(severity) ABSL_LOG_INTERNAL_LOG_IMPL(_##severity) // PLOG() // // `PLOG` behaves like `LOG` except that a description of the current state of // `errno` is appended to the streamed message. -#define PLOG(severity) ABSL_PLOG_IMPL(_##severity) +#define PLOG(severity) ABSL_LOG_INTERNAL_PLOG_IMPL(_##severity) // DLOG() // // `DLOG` behaves like `LOG` in debug mode (i.e. `#ifndef NDEBUG`). Otherwise // it compiles away and does nothing. Note that `DLOG(FATAL)` does not // terminate the program if `NDEBUG` is defined. -#define DLOG(severity) ABSL_DLOG_IMPL(_##severity) +#define DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity) // `LOG_IF` and friends add a second argument which specifies a condition. If // the condition is false, nothing is logged. // Example: // // LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; -#define LOG_IF(severity, condition) ABSL_LOG_IF_IMPL(_##severity, condition) -#define PLOG_IF(severity, condition) ABSL_PLOG_IF_IMPL(_##severity, condition) -#define DLOG_IF(severity, condition) ABSL_DLOG_IF_IMPL(_##severity, condition) +#define LOG_IF(severity, condition) \ + ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition) +#define PLOG_IF(severity, condition) \ + ABSL_LOG_INTERNAL_PLOG_IF_IMPL(_##severity, condition) +#define DLOG_IF(severity, condition) \ + ABSL_LOG_INTERNAL_DLOG_IF_IMPL(_##severity, condition) // LOG_EVERY_N // @@ -231,21 +234,24 @@ // // LOG_EVERY_N(WARNING, 1000) << "Got a packet with a bad CRC (" << COUNTER // << " total)"; -#define LOG_EVERY_N(severity, n) ABSL_LOG_EVERY_N_IMPL(_##severity, n) +#define LOG_EVERY_N(severity, n) \ + ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n) // LOG_FIRST_N // // `LOG_FIRST_N` behaves like `LOG_EVERY_N` except that the specified message is // logged when the counter's value is less than `n`. `LOG_FIRST_N` is // thread-safe. -#define LOG_FIRST_N(severity, n) ABSL_LOG_FIRST_N_IMPL(_##severity, n) +#define LOG_FIRST_N(severity, n) \ + ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n) // LOG_EVERY_POW_2 // // `LOG_EVERY_POW_2` behaves like `LOG_EVERY_N` except that the specified // message is logged when the counter's value is a power of 2. // `LOG_EVERY_POW_2` is thread-safe. -#define LOG_EVERY_POW_2(severity) ABSL_LOG_EVERY_POW_2_IMPL(_##severity) +#define LOG_EVERY_POW_2(severity) \ + ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity) // LOG_EVERY_N_SEC // @@ -257,19 +263,25 @@ // // LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far"; #define LOG_EVERY_N_SEC(severity, n_seconds) \ - ABSL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) + ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) -#define PLOG_EVERY_N(severity, n) ABSL_PLOG_EVERY_N_IMPL(_##severity, n) -#define PLOG_FIRST_N(severity, n) ABSL_PLOG_FIRST_N_IMPL(_##severity, n) -#define PLOG_EVERY_POW_2(severity) ABSL_PLOG_EVERY_POW_2_IMPL(_##severity) +#define PLOG_EVERY_N(severity, n) \ + ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(_##severity, n) +#define PLOG_FIRST_N(severity, n) \ + ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(_##severity, n) +#define PLOG_EVERY_POW_2(severity) \ + ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(_##severity) #define PLOG_EVERY_N_SEC(severity, n_seconds) \ - ABSL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) + ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) -#define DLOG_EVERY_N(severity, n) ABSL_DLOG_EVERY_N_IMPL(_##severity, n) -#define DLOG_FIRST_N(severity, n) ABSL_DLOG_FIRST_N_IMPL(_##severity, n) -#define DLOG_EVERY_POW_2(severity) ABSL_DLOG_EVERY_POW_2_IMPL(_##severity) +#define DLOG_EVERY_N(severity, n) \ + ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(_##severity, n) +#define DLOG_FIRST_N(severity, n) \ + ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(_##severity, n) +#define DLOG_EVERY_POW_2(severity) \ + ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(_##severity) #define DLOG_EVERY_N_SEC(severity, n_seconds) \ - ABSL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) + ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds) // `LOG_IF_EVERY_N` and friends behave as the corresponding `LOG_EVERY_N` // but neither increment a counter nor log a message if condition is false (as @@ -279,30 +291,30 @@ // LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER // << "th big cookie"; #define LOG_IF_EVERY_N(severity, condition, n) \ - ABSL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n) #define LOG_IF_FIRST_N(severity, condition, n) \ - ABSL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n) #define LOG_IF_EVERY_POW_2(severity, condition) \ - ABSL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition) #define LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ - ABSL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) + ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) #define PLOG_IF_EVERY_N(severity, condition, n) \ - ABSL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n) #define PLOG_IF_FIRST_N(severity, condition, n) \ - ABSL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n) #define PLOG_IF_EVERY_POW_2(severity, condition) \ - ABSL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) #define PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ - ABSL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) + ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) #define DLOG_IF_EVERY_N(severity, condition, n) \ - ABSL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n) #define DLOG_IF_FIRST_N(severity, condition, n) \ - ABSL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n) + ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n) #define DLOG_IF_EVERY_POW_2(severity, condition) \ - ABSL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) + ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition) #define DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \ - ABSL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) + ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds) #endif // ABSL_LOG_LOG_H_ diff --git a/absl/log/log_basic_test.cc b/absl/log/log_basic_test.cc index b8d87c94..7fc7111d 100644 --- a/absl/log/log_basic_test.cc +++ b/absl/log/log_basic_test.cc @@ -18,4 +18,4 @@ #define ABSL_TEST_LOG LOG #include "gtest/gtest.h" -#include "absl/log/log_basic_test_impl.h" +#include "absl/log/log_basic_test_impl.inc" diff --git a/absl/log/log_basic_test_impl.h b/absl/log/log_basic_test_impl.inc index 35c0b690..f3400095 100644 --- a/absl/log/log_basic_test_impl.h +++ b/absl/log/log_basic_test_impl.inc @@ -94,7 +94,7 @@ TEST_P(BasicLogTest, Info) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kInfo)), TimestampInMatchWindow(), @@ -123,7 +123,7 @@ TEST_P(BasicLogTest, Warning) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kWarning)), TimestampInMatchWindow(), @@ -152,7 +152,7 @@ TEST_P(BasicLogTest, Error) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kError)), TimestampInMatchWindow(), @@ -203,7 +203,7 @@ TEST_P(BasicLogDeathTest, Fatal) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)), TimestampInMatchWindow(), @@ -219,7 +219,7 @@ TEST_P(BasicLogDeathTest, Fatal) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)), TimestampInMatchWindow(), @@ -257,7 +257,7 @@ TEST_P(BasicLogDeathTest, QFatal) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)), TimestampInMatchWindow(), @@ -293,7 +293,7 @@ TEST_P(BasicLogTest, Level) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(severity)), TimestampInMatchWindow(), ThreadID(Eq(absl::base_internal::GetTID())), @@ -336,7 +336,7 @@ TEST_P(BasicLogDeathTest, Level) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)), TimestampInMatchWindow(), @@ -351,7 +351,7 @@ TEST_P(BasicLogDeathTest, Level) { EXPECT_CALL( test_sink, Send(AllOf(SourceFilename(Eq(__FILE__)), - SourceBasename(Eq("log_basic_test_impl.h")), + SourceBasename(Eq("log_basic_test_impl.inc")), SourceLine(Eq(log_line)), Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)), TimestampInMatchWindow(), diff --git a/absl/log/log_sink_test.cc b/absl/log/log_sink_test.cc index 8903da72..fa743060 100644 --- a/absl/log/log_sink_test.cc +++ b/absl/log/log_sink_test.cc @@ -18,7 +18,6 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/base/attributes.h" -#include "absl/base/internal/raw_logging.h" #include "absl/log/internal/test_actions.h" #include "absl/log/internal/test_helpers.h" #include "absl/log/internal/test_matchers.h" @@ -205,7 +204,7 @@ class ReentrancyTest : public ::testing::Test { << "The log is coming from *inside the sink*."; break; default: - ABSL_RAW_LOG(FATAL, "Invalid mode %d.\n", static_cast<int>(mode_)); + LOG(FATAL) << "Invalid mode " << static_cast<int>(mode_); } } diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel index 133c0659..19130ff7 100644 --- a/absl/random/BUILD.bazel +++ b/absl/random/BUILD.bazel @@ -189,7 +189,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/numeric:representation", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", @@ -244,7 +244,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", @@ -265,7 +265,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", @@ -292,8 +292,8 @@ cc_test( ":distributions", ":random", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", "//absl/container:flat_hash_map", + "//absl/log", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", @@ -314,7 +314,7 @@ cc_test( ":distributions", ":random", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/numeric:representation", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", @@ -338,7 +338,7 @@ cc_test( ":distributions", ":random", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/numeric:representation", "//absl/random/internal:distribution_test_util", "//absl/random/internal:sequence_urbg", @@ -360,7 +360,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", @@ -385,7 +385,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/numeric:representation", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", @@ -406,7 +406,7 @@ cc_test( deps = [ ":distributions", ":random", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/random/internal:distribution_test_util", "//absl/random/internal:pcg_engine", "//absl/random/internal:sequence_urbg", diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt index c74fd300..bd363d88 100644 --- a/absl/random/CMakeLists.txt +++ b/absl/random/CMakeLists.txt @@ -260,13 +260,13 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::log absl::numeric_representation absl::random_distributions absl::random_random absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_internal_pcg_engine - absl::raw_logging_internal absl::strings absl::str_format GTest::gmock @@ -299,6 +299,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + DEPS absl::random_distributions absl::random_random absl::raw_logging_internal @@ -315,12 +316,13 @@ absl_cc_test( ${ABSL_TEST_COPTS} LINKOPTS ${ABSL_DEFAULT_LINKOPTS} + DEPS + absl::log absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random - absl::raw_logging_internal absl::strings absl::str_format GTest::gmock @@ -337,12 +339,12 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::log absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random - absl::raw_logging_internal absl::strings GTest::gmock GTest::gtest_main @@ -362,10 +364,10 @@ absl_cc_test( absl::random_random absl::core_headers absl::flat_hash_map + absl::log absl::random_internal_distribution_test_util absl::random_internal_pcg_engine absl::random_internal_sequence_urbg - absl::raw_logging_internal absl::strings absl::str_format GTest::gmock @@ -383,13 +385,13 @@ absl_cc_test( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::core_headers + absl::log absl::numeric_representation absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random - absl::raw_logging_internal absl::strings absl::str_format GTest::gmock @@ -407,12 +409,12 @@ absl_cc_test( ${ABSL_DEFAULT_LINKOPTS} DEPS absl::core_headers + absl::log absl::numeric_representation absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_sequence_urbg absl::random_random - absl::raw_logging_internal absl::strings absl::str_format GTest::gmock @@ -429,12 +431,12 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::log absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random - absl::raw_logging_internal absl::strings GTest::gmock GTest::gtest_main @@ -450,6 +452,7 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::log absl::numeric_representation absl::random_distributions absl::random_internal_distribution_test_util @@ -471,12 +474,12 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::log absl::random_distributions absl::random_internal_distribution_test_util absl::random_internal_pcg_engine absl::random_internal_sequence_urbg absl::random_random - absl::raw_logging_internal absl::strings GTest::gmock GTest::gtest_main @@ -1090,9 +1093,9 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::log absl::random_internal_explicit_seed_seq absl::random_internal_randen_engine - absl::raw_logging_internal absl::strings absl::time GTest::gmock @@ -1142,10 +1145,10 @@ absl_cc_test( LINKOPTS ${ABSL_DEFAULT_LINKOPTS} DEPS + absl::log absl::random_internal_platform absl::random_internal_randen_hwaes absl::random_internal_randen_hwaes_impl - absl::raw_logging_internal absl::str_format GTest::gmock GTest::gtest diff --git a/absl/random/benchmarks.cc b/absl/random/benchmarks.cc index 87bbb981..0900e818 100644 --- a/absl/random/benchmarks.cc +++ b/absl/random/benchmarks.cc @@ -62,7 +62,7 @@ class PrecompiledSeedSeq { public: using result_type = uint32_t; - PrecompiledSeedSeq() {} + PrecompiledSeedSeq() = default; template <typename Iterator> PrecompiledSeedSeq(Iterator begin, Iterator end) {} diff --git a/absl/random/beta_distribution_test.cc b/absl/random/beta_distribution_test.cc index c16fbb4f..c93b2a33 100644 --- a/absl/random/beta_distribution_test.cc +++ b/absl/random/beta_distribution_test.cc @@ -28,7 +28,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/numeric/internal/representation.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" @@ -107,8 +107,8 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) { }; for (TypeParam alpha : kValues) { for (TypeParam beta : kValues) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("Smoke test for Beta(%a, %a)", alpha, beta)); + LOG(INFO) << absl::StreamFormat("Smoke test for Beta(%a, %a)", alpha, + beta); param_type param(alpha, beta); absl::beta_distribution<TypeParam> before(alpha, beta); @@ -327,15 +327,13 @@ bool BetaDistributionTest::SingleZTestOnMeanAndVariance(double p, absl::random_internal::Near("z", z_mean, 0.0, max_err) && absl::random_internal::Near("z_variance", z_variance, 0.0, max_err); if (!pass) { - ABSL_INTERNAL_LOG( - INFO, - absl::StrFormat( - "Beta(%f, %f), " - "mean: sample %f, expect %f, which is %f stddevs away, " - "variance: sample %f, expect %f, which is %f stddevs away.", - alpha_, beta_, m.mean, Mean(), - std::abs(m.mean - Mean()) / mean_stddev, m.variance, Variance(), - std::abs(m.variance - Variance()) / variance_stddev)); + LOG(INFO) << "Beta(" << alpha_ << ", " << beta_ << "), mean: sample " + << m.mean << ", expect " << Mean() << ", which is " + << std::abs(m.mean - Mean()) / mean_stddev + << " stddevs away, variance: sample " << m.variance << ", expect " + << Variance() << ", which is " + << std::abs(m.variance - Variance()) / variance_stddev + << " stddevs away."; } return pass; } @@ -396,18 +394,15 @@ bool BetaDistributionTest::SingleChiSquaredTest(double p, size_t samples, const bool pass = (absl::random_internal::ChiSquarePValue(chi_square, dof) >= p); if (!pass) { - for (int i = 0; i < cutoffs.size(); i++) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("cutoff[%d] = %f, actual count %d, expected %d", - i, cutoffs[i], counts[i], - static_cast<int>(expected[i]))); + for (size_t i = 0; i < cutoffs.size(); i++) { + LOG(INFO) << "cutoff[" << i << "] = " << cutoffs[i] << ", actual count " + << counts[i] << ", expected " << static_cast<int>(expected[i]); } - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat( - "Beta(%f, %f) %s %f, p = %f", alpha_, beta_, - absl::random_internal::kChiSquared, chi_square, - absl::random_internal::ChiSquarePValue(chi_square, dof))); + LOG(INFO) << "Beta(" << alpha_ << ", " << beta_ << ") " + << absl::random_internal::kChiSquared << " " << chi_square + << ", p = " + << absl::random_internal::ChiSquarePValue(chi_square, dof); } return pass; } diff --git a/absl/random/discrete_distribution_test.cc b/absl/random/discrete_distribution_test.cc index e528a6a7..32405ea9 100644 --- a/absl/random/discrete_distribution_test.cc +++ b/absl/random/discrete_distribution_test.cc @@ -26,7 +26,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" #include "absl/random/internal/pcg_engine.h" @@ -194,7 +194,7 @@ TEST(DiscreteDistributionTest, ChiSquaredTest50) { absl::StrAppend(&msg, kChiSquared, " p-value ", p_value, "\n"); absl::StrAppend(&msg, "High ", kChiSquared, " value: ", chi_square, " > ", kThreshold); - ABSL_RAW_LOG(INFO, "%s", msg.c_str()); + LOG(INFO) << msg; FAIL() << msg; } } diff --git a/absl/random/exponential_distribution_test.cc b/absl/random/exponential_distribution_test.cc index 3c44d9ec..fb9a0d16 100644 --- a/absl/random/exponential_distribution_test.cc +++ b/absl/random/exponential_distribution_test.cc @@ -29,8 +29,8 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" +#include "absl/log/log.h" #include "absl/numeric/internal/representation.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" @@ -115,9 +115,8 @@ TYPED_TEST(ExponentialDistributionTypedTest, SerializeTest) { if (sample < sample_min) sample_min = sample; } if (!std::is_same<TypeParam, long double>::value) { - ABSL_INTERNAL_LOG(INFO, - absl::StrFormat("Range {%f}: %f, %f, lambda=%f", lambda, - sample_min, sample_max, lambda)); + LOG(INFO) << "Range {" << lambda << "}: " << sample_min << ", " + << sample_max << ", lambda=" << lambda; } std::stringstream ss; @@ -219,17 +218,16 @@ bool ExponentialDistributionTests::SingleZTest(const double p, const bool pass = absl::random_internal::Near("z", z, 0.0, max_err); if (!pass) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("p=%f max_err=%f\n" - " lambda=%f\n" - " mean=%f vs. %f\n" - " stddev=%f vs. %f\n" - " skewness=%f vs. %f\n" - " kurtosis=%f vs. %f\n" - " z=%f vs. 0", - p, max_err, lambda(), m.mean, mean(), - std::sqrt(m.variance), stddev(), m.skewness, - skew(), m.kurtosis, kurtosis(), z)); + // clang-format off + LOG(INFO) + << "p=" << p << " max_err=" << max_err << "\n" + " lambda=" << lambda() << "\n" + " mean=" << m.mean << " vs. " << mean() << "\n" + " stddev=" << std::sqrt(m.variance) << " vs. " << stddev() << "\n" + " skewness=" << m.skewness << " vs. " << skew() << "\n" + " kurtosis=" << m.kurtosis << " vs. " << kurtosis() << "\n" + " z=" << z << " vs. 0"; + // clang-format on } return pass; } @@ -274,16 +272,16 @@ double ExponentialDistributionTests::SingleChiSquaredTest() { double p = absl::random_internal::ChiSquarePValue(chi_square, dof); if (chi_square > threshold) { - for (int i = 0; i < cutoffs.size(); i++) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("%d : (%f) = %d", i, cutoffs[i], counts[i])); + for (size_t i = 0; i < cutoffs.size(); i++) { + LOG(INFO) << i << " : (" << cutoffs[i] << ") = " << counts[i]; } - ABSL_INTERNAL_LOG(INFO, - absl::StrCat("lambda ", lambda(), "\n", // - " expected ", expected, "\n", // - kChiSquared, " ", chi_square, " (", p, ")\n", - kChiSquared, " @ 0.98 = ", threshold)); + // clang-format off + LOG(INFO) << "lambda " << lambda() << "\n" + " expected " << expected << "\n" + << kChiSquared << " " << chi_square << " (" << p << ")\n" + << kChiSquared << " @ 0.98 = " << threshold; + // clang-format on } return p; } diff --git a/absl/random/gaussian_distribution_test.cc b/absl/random/gaussian_distribution_test.cc index 4584ac92..bad3476f 100644 --- a/absl/random/gaussian_distribution_test.cc +++ b/absl/random/gaussian_distribution_test.cc @@ -26,8 +26,8 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" +#include "absl/log/log.h" #include "absl/numeric/internal/representation.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" @@ -116,9 +116,8 @@ TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) { EXPECT_LE(sample, before.max()) << before; } if (!std::is_same<TypeParam, long double>::value) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("Range{%f, %f}: %f, %f", mean, stddev, - sample_min, sample_max)); + LOG(INFO) << "Range{" << mean << ", " << stddev << "}: " << sample_min + << ", " << sample_max; } std::stringstream ss; @@ -240,17 +239,16 @@ bool GaussianDistributionTests::SingleZTest(const double p, (std::pow(m.skewness, 2.0) + std::pow(m.kurtosis - 3.0, 2.0) / 4.0); if (!pass || jb > 9.21) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("p=%f max_err=%f\n" - " mean=%f vs. %f\n" - " stddev=%f vs. %f\n" - " skewness=%f vs. %f\n" - " kurtosis=%f vs. %f\n" - " z=%f vs. 0\n" - " jb=%f vs. 9.21", - p, max_err, m.mean, mean(), std::sqrt(m.variance), - stddev(), m.skewness, skew(), m.kurtosis, - kurtosis(), z, jb)); + // clang-format off + LOG(INFO) + << "p=" << p << " max_err=" << max_err << "\n" + " mean=" << m.mean << " vs. " << mean() << "\n" + " stddev=" << std::sqrt(m.variance) << " vs. " << stddev() << "\n" + " skewness=" << m.skewness << " vs. " << skew() << "\n" + " kurtosis=" << m.kurtosis << " vs. " << kurtosis() << "\n" + " z=" << z << " vs. 0\n" + " jb=" << jb << " vs. 9.21"; + // clang-format on } return pass; } @@ -297,16 +295,16 @@ double GaussianDistributionTests::SingleChiSquaredTest() { // Log if the chi_square value is above the threshold. if (chi_square > threshold) { - for (int i = 0; i < cutoffs.size(); i++) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("%d : (%f) = %d", i, cutoffs[i], counts[i])); + for (size_t i = 0; i < cutoffs.size(); i++) { + LOG(INFO) << i << " : (" << cutoffs[i] << ") = " << counts[i]; } - ABSL_INTERNAL_LOG( - INFO, absl::StrCat("mean=", mean(), " stddev=", stddev(), "\n", // - " expected ", expected, "\n", // - kChiSquared, " ", chi_square, " (", p, ")\n", // - kChiSquared, " @ 0.98 = ", threshold)); + // clang-format off + LOG(INFO) << "mean=" << mean() << " stddev=" << stddev() << "\n" + " expected " << expected << "\n" + << kChiSquared << " " << chi_square << " (" << p << ")\n" + << kChiSquared << " @ 0.98 = " << threshold; + // clang-format on } return p; } diff --git a/absl/random/generators_test.cc b/absl/random/generators_test.cc index c3675674..20091309 100644 --- a/absl/random/generators_test.cc +++ b/absl/random/generators_test.cc @@ -117,6 +117,7 @@ void TestBernoulli(URBG* gen) { absl::Bernoulli(*gen, 0.5); } + template <typename URBG> void TestZipf(URBG* gen) { absl::Zipf<int>(*gen, 100); diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel index a51c9375..37f4d6e2 100644 --- a/absl/random/internal/BUILD.bazel +++ b/absl/random/internal/BUILD.bazel @@ -601,7 +601,7 @@ cc_test( deps = [ ":explicit_seed_seq", ":randen_engine", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/strings", "//absl/time", "@com_google_googletest//:gtest_main", @@ -646,7 +646,7 @@ cc_test( ":platform", ":randen_hwaes", ":randen_hwaes_impl", # build_cleaner: keep - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/strings:str_format", "@com_google_googletest//:gtest", ], @@ -707,8 +707,10 @@ cc_test( ], deps = [ ":nanobenchmark", - "//absl/base:raw_logging_internal", + "//absl/log", + "//absl/log:check", "//absl/strings", + "//absl/strings:str_format", ], ) diff --git a/absl/random/internal/nanobenchmark_test.cc b/absl/random/internal/nanobenchmark_test.cc index f1571e26..d4f1028d 100644 --- a/absl/random/internal/nanobenchmark_test.cc +++ b/absl/random/internal/nanobenchmark_test.cc @@ -14,8 +14,10 @@ #include "absl/random/internal/nanobenchmark.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/numbers.h" +#include "absl/strings/str_format.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -36,16 +38,16 @@ void MeasureDiv(const FuncInput (&inputs)[N]) { params.max_evals = 6; // avoid test timeout const size_t num_results = Measure(&Div, nullptr, inputs, N, results, params); if (num_results == 0) { - ABSL_RAW_LOG( - WARNING, - "WARNING: Measurement failed, should not happen when using " - "PinThreadToCPU unless the region to measure takes > 1 second.\n"); + LOG(WARNING) + << "WARNING: Measurement failed, should not happen when using " + "PinThreadToCPU unless the region to measure takes > 1 second."; return; } for (size_t i = 0; i < num_results; ++i) { - ABSL_RAW_LOG(INFO, "%5zu: %6.2f ticks; MAD=%4.2f%%\n", results[i].input, - results[i].ticks, results[i].variability * 100.0); - ABSL_RAW_CHECK(results[i].ticks != 0.0f, "Zero duration"); + LOG(INFO) << absl::StreamFormat("%5u: %6.2f ticks; MAD=%4.2f%%\n", + results[i].input, results[i].ticks, + results[i].variability * 100.0); + CHECK_NE(results[i].ticks, 0.0f) << "Zero duration"; } } @@ -54,7 +56,7 @@ void RunAll(const int argc, char* argv[]) { int cpu = -1; if (argc == 2) { if (!absl::SimpleAtoi(argv[1], &cpu)) { - ABSL_RAW_LOG(FATAL, "The optional argument must be a CPU number >= 0.\n"); + LOG(FATAL) << "The optional argument must be a CPU number >= 0."; } } PinThreadToCPU(cpu); diff --git a/absl/random/internal/randen_detect.cc b/absl/random/internal/randen_detect.cc index 6dababa3..bdeab877 100644 --- a/absl/random/internal/randen_detect.cc +++ b/absl/random/internal/randen_detect.cc @@ -45,6 +45,10 @@ #if defined(ABSL_INTERNAL_USE_X86_CPUID) #if defined(_WIN32) || defined(_WIN64) #include <intrin.h> // NOLINT(build/include_order) +#elif ABSL_HAVE_BUILTIN(__cpuid) +// MSVC-equivalent __cpuid intrinsic declaration for clang-like compilers +// for non-Windows build environments. +extern void __cpuid(int[4], int); #else // MSVC-equivalent __cpuid intrinsic function. static void __cpuid(int cpu_info[4], int info_type) { diff --git a/absl/random/internal/randen_engine_test.cc b/absl/random/internal/randen_engine_test.cc index c8e7685b..a94f4916 100644 --- a/absl/random/internal/randen_engine_test.cc +++ b/absl/random/internal/randen_engine_test.cc @@ -21,7 +21,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/random/internal/explicit_seed_seq.h" #include "absl/strings/str_cat.h" #include "absl/time/clock.h" @@ -645,9 +645,8 @@ TEST(RandenTest, IsFastOrSlow) { } auto duration = absl::GetCurrentTimeNanos() - start; - ABSL_INTERNAL_LOG(INFO, absl::StrCat(static_cast<double>(duration) / - static_cast<double>(kCount), - "ns")); + LOG(INFO) << static_cast<double>(duration) / static_cast<double>(kCount) + << "ns"; EXPECT_GT(sum, 0); EXPECT_GE(duration, kCount); // Should be slower than 1ns per call. diff --git a/absl/random/internal/randen_hwaes_test.cc b/absl/random/internal/randen_hwaes_test.cc index 2348b55c..00d96efd 100644 --- a/absl/random/internal/randen_hwaes_test.cc +++ b/absl/random/internal/randen_hwaes_test.cc @@ -16,7 +16,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/random/internal/platform.h" #include "absl/random/internal/randen_detect.h" #include "absl/random/internal/randen_traits.h" @@ -67,32 +67,32 @@ TEST(RandenHwAesTest, Default) { int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); - ABSL_RAW_LOG(INFO, "ABSL_HAVE_ACCELERATED_AES=%d", ABSL_HAVE_ACCELERATED_AES); - ABSL_RAW_LOG(INFO, "ABSL_RANDOM_INTERNAL_AES_DISPATCH=%d", - ABSL_RANDOM_INTERNAL_AES_DISPATCH); + LOG(INFO) << "ABSL_HAVE_ACCELERATED_AES=" << ABSL_HAVE_ACCELERATED_AES; + LOG(INFO) << "ABSL_RANDOM_INTERNAL_AES_DISPATCH=" + << ABSL_RANDOM_INTERNAL_AES_DISPATCH; #if defined(ABSL_ARCH_X86_64) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_X86_64"); + LOG(INFO) << "ABSL_ARCH_X86_64"; #elif defined(ABSL_ARCH_X86_32) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_X86_32"); + LOG(INFO) << "ABSL_ARCH_X86_32"; #elif defined(ABSL_ARCH_AARCH64) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_AARCH64"); + LOG(INFO) << "ABSL_ARCH_AARCH64"; #elif defined(ABSL_ARCH_ARM) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_ARM"); + LOG(INFO) << "ABSL_ARCH_ARM"; #elif defined(ABSL_ARCH_PPC) - ABSL_RAW_LOG(INFO, "ABSL_ARCH_PPC"); + LOG(INFO) << "ABSL_ARCH_PPC"; #else - ABSL_RAW_LOG(INFO, "ARCH Unknown"); + LOG(INFO) << "ARCH Unknown"; #endif int x = absl::random_internal::HasRandenHwAesImplementation(); - ABSL_RAW_LOG(INFO, "HasRandenHwAesImplementation = %d", x); + LOG(INFO) << "HasRandenHwAesImplementation = " << x; int y = absl::random_internal::CPUSupportsRandenHwAes(); - ABSL_RAW_LOG(INFO, "CPUSupportsRandenHwAes = %d", x); + LOG(INFO) << "CPUSupportsRandenHwAes = " << x; if (!x || !y) { - ABSL_RAW_LOG(INFO, "Skipping Randen HWAES tests."); + LOG(INFO) << "Skipping Randen HWAES tests."; return 0; } return RUN_ALL_TESTS(); diff --git a/absl/random/log_uniform_int_distribution_test.cc b/absl/random/log_uniform_int_distribution_test.cc index 0d0fcb95..5df3edac 100644 --- a/absl/random/log_uniform_int_distribution_test.cc +++ b/absl/random/log_uniform_int_distribution_test.cc @@ -24,7 +24,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" #include "absl/random/internal/pcg_engine.h" @@ -108,8 +108,7 @@ TYPED_TEST(LogUniformIntDistributionTypeTest, SerializeTest) { if (sample > sample_max) sample_max = sample; if (sample < sample_min) sample_min = sample; } - ABSL_INTERNAL_LOG(INFO, - absl::StrCat("Range: ", +sample_min, ", ", +sample_max)); + LOG(INFO) << "Range: " << sample_min << ", " << sample_max; } } @@ -182,16 +181,14 @@ double LogUniformIntChiSquaredTest::ChiSquaredTestImpl() { const double p = absl::random_internal::ChiSquarePValue(chi_square, dof); if (chi_square > threshold) { - ABSL_INTERNAL_LOG(INFO, "values"); + LOG(INFO) << "values"; for (size_t i = 0; i < buckets.size(); i++) { - ABSL_INTERNAL_LOG(INFO, absl::StrCat(i, ": ", buckets[i])); + LOG(INFO) << i << ": " << buckets[i]; } - ABSL_INTERNAL_LOG(INFO, - absl::StrFormat("trials=%d\n" - "%s(data, %d) = %f (%f)\n" - "%s @ 0.98 = %f", - trials, kChiSquared, dof, chi_square, p, - kChiSquared, threshold)); + LOG(INFO) << "trials=" << trials << "\n" + << kChiSquared << "(data, " << dof << ") = " << chi_square << " (" + << p << ")\n" + << kChiSquared << " @ 0.98 = " << threshold; } return p; } diff --git a/absl/random/poisson_distribution_test.cc b/absl/random/poisson_distribution_test.cc index 4f585b9b..54755960 100644 --- a/absl/random/poisson_distribution_test.cc +++ b/absl/random/poisson_distribution_test.cc @@ -25,9 +25,9 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" #include "absl/container/flat_hash_map.h" +#include "absl/log/log.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" #include "absl/random/internal/pcg_engine.h" @@ -134,8 +134,8 @@ TYPED_TEST(PoissonDistributionInterfaceTest, SerializeTest) { if (sample < sample_min) sample_min = sample; } - ABSL_INTERNAL_LOG(INFO, absl::StrCat("Range {", param.mean(), "}: ", - +sample_min, ", ", +sample_max)); + LOG(INFO) << "Range {" << param.mean() << "}: " << sample_min << ", " + << sample_max; // Validate stream serialization. std::stringstream ss; @@ -188,10 +188,9 @@ class PoissonModel { } void LogCDF() { - ABSL_INTERNAL_LOG(INFO, absl::StrCat("CDF (mean = ", mean_, ")")); + LOG(INFO) << "CDF (mean = " << mean_ << ")"; for (const auto c : cdf_) { - ABSL_INTERNAL_LOG(INFO, - absl::StrCat(c.index, ": pmf=", c.pmf, " cdf=", c.cdf)); + LOG(INFO) << c.index << ": pmf=" << c.pmf << " cdf=" << c.cdf; } } @@ -286,16 +285,15 @@ bool PoissonDistributionZTest::SingleZTest(const double p, const bool pass = absl::random_internal::Near("z", z, 0.0, max_err); if (!pass) { - ABSL_INTERNAL_LOG( - INFO, absl::StrFormat("p=%f max_err=%f\n" - " mean=%f vs. %f\n" - " stddev=%f vs. %f\n" - " skewness=%f vs. %f\n" - " kurtosis=%f vs. %f\n" - " z=%f", - p, max_err, m.mean, mean(), std::sqrt(m.variance), - stddev(), m.skewness, skew(), m.kurtosis, - kurtosis(), z)); + // clang-format off + LOG(INFO) + << "p=" << p << " max_err=" << max_err << "\n" + " mean=" << m.mean << " vs. " << mean() << "\n" + " stddev=" << std::sqrt(m.variance) << " vs. " << stddev() << "\n" + " skewness=" << m.skewness << " vs. " << skew() << "\n" + " kurtosis=" << m.kurtosis << " vs. " << kurtosis() << "\n" + " z=" << z; + // clang-format on } return pass; } @@ -439,17 +437,16 @@ double PoissonDistributionChiSquaredTest::ChiSquaredTestImpl() { if (chi_square > threshold) { LogCDF(); - ABSL_INTERNAL_LOG(INFO, absl::StrCat("VALUES buckets=", counts.size(), - " samples=", kSamples)); + LOG(INFO) << "VALUES buckets=" << counts.size() + << " samples=" << kSamples; for (size_t i = 0; i < counts.size(); i++) { - ABSL_INTERNAL_LOG( - INFO, absl::StrCat(cutoffs_[i], ": ", counts[i], " vs. E=", e[i])); + LOG(INFO) << cutoffs_[i] << ": " << counts[i] << " vs. E=" << e[i]; } - ABSL_INTERNAL_LOG( - INFO, - absl::StrCat(kChiSquared, "(data, dof=", dof, ") = ", chi_square, " (", - p, ")\n", " vs.\n", kChiSquared, " @ 0.98 = ", threshold)); + LOG(INFO) << kChiSquared << "(data, dof=" << dof << ") = " << chi_square + << " (" << p << ")\n" + << " vs.\n" + << kChiSquared << " @ 0.98 = " << threshold; } return p; } diff --git a/absl/random/uniform_int_distribution_test.cc b/absl/random/uniform_int_distribution_test.cc index a830117a..b40d6185 100644 --- a/absl/random/uniform_int_distribution_test.cc +++ b/absl/random/uniform_int_distribution_test.cc @@ -24,7 +24,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" #include "absl/random/internal/pcg_engine.h" @@ -107,8 +107,7 @@ TYPED_TEST(UniformIntDistributionTest, ParamSerializeTest) { sample_min = sample; } } - std::string msg = absl::StrCat("Range: ", +sample_min, ", ", +sample_max); - ABSL_RAW_LOG(INFO, "%s", msg.c_str()); + LOG(INFO) << "Range: " << sample_min << ", " << sample_max; } } @@ -210,7 +209,7 @@ TYPED_TEST(UniformIntDistributionTest, ChiSquaredTest50) { absl::StrAppend(&msg, kChiSquared, " p-value ", p_value, "\n"); absl::StrAppend(&msg, "High ", kChiSquared, " value: ", chi_square, " > ", kThreshold); - ABSL_RAW_LOG(INFO, "%s", msg.c_str()); + LOG(INFO) << msg; FAIL() << msg; } } diff --git a/absl/random/uniform_real_distribution_test.cc b/absl/random/uniform_real_distribution_test.cc index 07f199d3..260aac96 100644 --- a/absl/random/uniform_real_distribution_test.cc +++ b/absl/random/uniform_real_distribution_test.cc @@ -26,7 +26,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/numeric/internal/representation.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/distribution_test_util.h" @@ -182,9 +182,8 @@ TYPED_TEST(UniformRealDistributionTest, ParamSerializeTest) { if (!std::is_same<real_type, long double>::value) { // static_cast<double>(long double) can overflow. - std::string msg = absl::StrCat("Range: ", static_cast<double>(sample_min), - ", ", static_cast<double>(sample_max)); - ABSL_RAW_LOG(INFO, "%s", msg.c_str()); + LOG(INFO) << "Range: " << static_cast<double>(sample_min) << ", " + << static_cast<double>(sample_max); } } } @@ -324,7 +323,7 @@ TYPED_TEST(UniformRealDistributionTest, ChiSquaredTest50) { absl::StrAppend(&msg, kChiSquared, " p-value ", p_value, "\n"); absl::StrAppend(&msg, "High ", kChiSquared, " value: ", chi_square, " > ", kThreshold); - ABSL_RAW_LOG(INFO, "%s", msg.c_str()); + LOG(INFO) << msg; FAIL() << msg; } } diff --git a/absl/random/zipf_distribution_test.cc b/absl/random/zipf_distribution_test.cc index c8bb89db..801ec4f6 100644 --- a/absl/random/zipf_distribution_test.cc +++ b/absl/random/zipf_distribution_test.cc @@ -25,7 +25,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/random/internal/chi_square.h" #include "absl/random/internal/pcg_engine.h" #include "absl/random/internal/sequence_urbg.h" @@ -102,8 +102,7 @@ TYPED_TEST(ZipfDistributionTypedTest, SerializeTest) { if (sample > sample_max) sample_max = sample; if (sample < sample_min) sample_min = sample; } - ABSL_INTERNAL_LOG(INFO, - absl::StrCat("Range: ", +sample_min, ", ", +sample_max)); + LOG(INFO) << "Range: " << sample_min << ", " << sample_max; } } @@ -303,18 +302,15 @@ TEST_P(ZipfTest, ChiSquaredTest) { // Log if the chi_squared value is above the threshold. if (chi_square > threshold) { - ABSL_INTERNAL_LOG(INFO, "values"); + LOG(INFO) << "values"; for (size_t i = 0; i < expected.size(); i++) { - ABSL_INTERNAL_LOG(INFO, absl::StrCat(points[i], ": ", buckets[i], - " vs. E=", expected[i])); + LOG(INFO) << points[i] << ": " << buckets[i] << " vs. E=" << expected[i]; } - ABSL_INTERNAL_LOG(INFO, absl::StrCat("trials ", trials)); - ABSL_INTERNAL_LOG(INFO, - absl::StrCat("mean ", avg, " vs. expected ", mean())); - ABSL_INTERNAL_LOG(INFO, absl::StrCat(kChiSquared, "(data, ", dof, ") = ", - chi_square, " (", p_actual, ")")); - ABSL_INTERNAL_LOG(INFO, - absl::StrCat(kChiSquared, " @ 0.9995 = ", threshold)); + LOG(INFO) << "trials " << trials; + LOG(INFO) << "mean " << avg << " vs. expected " << mean(); + LOG(INFO) << kChiSquared << "(data, " << dof << ") = " << chi_square << " (" + << p_actual << ")"; + LOG(INFO) << kChiSquared << " @ 0.9995 = " << threshold; FAIL() << kChiSquared << " value of " << chi_square << " is above the threshold."; } diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h index 873eb5c2..6198e726 100644 --- a/absl/status/internal/status_internal.h +++ b/absl/status/internal/status_internal.h @@ -66,6 +66,10 @@ struct StatusRep { std::atomic<int32_t> ref; absl::StatusCode code; + + // As an internal implementation detail, we guarantee that if status.message() + // is non-empty, then the resulting string_view is null terminated. + // This is required to implement 'StatusMessageAsCStr(...)' std::string message; std::unique_ptr<status_internal::Payloads> payloads; }; diff --git a/absl/status/status.cc b/absl/status/status.cc index d011075a..26e68294 100644 --- a/absl/status/status.cc +++ b/absl/status/status.cc @@ -616,5 +616,12 @@ std::string* MakeCheckFailString(const absl::Status* status, } // namespace status_internal +const char* StatusMessageAsCStr(const Status& status) { + // As an internal implementation detail, we guarantee that if status.message() + // is non-empty, then the resulting string_view is null terminated. + auto sv_message = status.message(); + return sv_message.empty() ? "" : sv_message.data(); +} + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/status/status.h b/absl/status/status.h index c6c1cd41..595064c0 100644 --- a/absl/status/status.h +++ b/absl/status/status.h @@ -886,6 +886,15 @@ inline Status OkStatus() { return Status(); } // message-less kCancelled errors are common in the infrastructure. inline Status CancelledError() { return Status(absl::StatusCode::kCancelled); } +// Retrieves a message's status as a null terminated C string. The lifetime of +// this string is tied to the lifetime of the status object itself. +// +// If the status's message is empty, the empty string is returned. +// +// StatusMessageAsCStr exists for C support. Use `status.message()` in C++. +const char* StatusMessageAsCStr( + const Status& status ABSL_ATTRIBUTE_LIFETIME_BOUND); + ABSL_NAMESPACE_END } // namespace absl diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc index 74a64ace..898a9cb2 100644 --- a/absl/status/status_test.cc +++ b/absl/status/status_test.cc @@ -132,6 +132,29 @@ TEST(Status, ConstructorWithCodeMessage) { } } +TEST(Status, StatusMessageCStringTest) { + { + absl::Status status = absl::OkStatus(); + EXPECT_EQ(status.message(), ""); + EXPECT_STREQ(absl::StatusMessageAsCStr(status), ""); + EXPECT_EQ(status.message(), absl::StatusMessageAsCStr(status)); + EXPECT_NE(absl::StatusMessageAsCStr(status), nullptr); + } + { + absl::Status status; + EXPECT_EQ(status.message(), ""); + EXPECT_NE(absl::StatusMessageAsCStr(status), nullptr); + EXPECT_STREQ(absl::StatusMessageAsCStr(status), ""); + } + { + absl::Status status(absl::StatusCode::kInternal, "message"); + EXPECT_FALSE(status.ok()); + EXPECT_EQ(absl::StatusCode::kInternal, status.code()); + EXPECT_EQ("message", status.message()); + EXPECT_STREQ("message", absl::StatusMessageAsCStr(status)); + } +} + TEST(Status, ConstructOutOfRangeCode) { const int kRawCode = 9999; absl::Status status(static_cast<absl::StatusCode>(kRawCode), ""); diff --git a/absl/status/statusor.h b/absl/status/statusor.h index beedd795..935366d5 100644 --- a/absl/status/statusor.h +++ b/absl/status/statusor.h @@ -146,7 +146,7 @@ class ABSL_MUST_USE_RESULT StatusOr; // // absl::StatusOr<int> i = GetCount(); // if (i.ok()) { -// updated_total += *i +// updated_total += *i; // } // // NOTE: using `absl::StatusOr<T>::value()` when no valid value is present will @@ -612,6 +612,21 @@ class StatusOr : private internal_statusor::StatusOrData<T>, return this->data_; } + // StatusOr<T>::AssignStatus() + // + // Sets the status of `absl::StatusOr<T>` to the given non-ok status value. + // + // NOTE: We recommend using the constructor and `operator=` where possible. + // This method is intended for use in generic programming, to enable setting + // the status of a `StatusOr<T>` when `T` may be `Status`. In that case, the + // constructor and `operator=` would assign into the inner value of type + // `Status`, rather than status of the `StatusOr` (b/280392796). + // + // REQUIRES: !Status(std::forward<U>(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. + using internal_statusor::StatusOrData<T>::AssignStatus; + private: using internal_statusor::StatusOrData<T>::Assign; template <typename U> diff --git a/absl/status/statusor_test.cc b/absl/status/statusor_test.cc index 29021543..e65f5d27 100644 --- a/absl/status/statusor_test.cc +++ b/absl/status/statusor_test.cc @@ -1844,4 +1844,37 @@ TEST(StatusOr, AssignmentFromTypeConvertibleToStatus) { } } +TEST(StatusOr, StatusAssignmentFromStatusError) { + absl::StatusOr<absl::Status> statusor; + statusor.AssignStatus(absl::CancelledError()); + + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), absl::CancelledError()); +} + +#if GTEST_HAS_DEATH_TEST +TEST(StatusOr, StatusAssignmentFromStatusOk) { + EXPECT_DEBUG_DEATH( + { + absl::StatusOr<absl::Status> statusor; + // This will DCHECK. + statusor.AssignStatus(absl::OkStatus()); + // In optimized mode, we are actually going to get error::INTERNAL for + // status here, rather than crashing, so check that. + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status().code(), absl::StatusCode::kInternal); + }, + "An OK status is not a valid constructor argument to StatusOr<T>"); +} +#endif + +TEST(StatusOr, StatusAssignmentFromTypeConvertibleToStatus) { + CustomType<MyType, kConvToStatus> v; + absl::StatusOr<MyType> statusor; + statusor.AssignStatus(v); + + EXPECT_FALSE(statusor.ok()); + EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); +} + } // namespace diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index e48a9a0a..bd33c533 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -774,10 +774,10 @@ cc_test( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", - "//absl/base:raw_logging_internal", "//absl/container:fixed_array", "//absl/hash", "//absl/log", + "//absl/log:check", "//absl/random", "@com_google_googletest//:gtest_main", ], @@ -1019,7 +1019,7 @@ cc_test( ":pow10_helper", ":strings", "//absl/base:config", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/random", "//absl/random:distributions", "@com_google_googletest//:gtest_main", @@ -1096,7 +1096,7 @@ cc_test( deps = [ ":strings", "//absl/base:config", - "//absl/base:raw_logging_internal", + "//absl/log:check", "@com_google_googletest//:gtest_main", ], ) @@ -1253,6 +1253,7 @@ cc_test( ":strings", "//absl/base:core_headers", "//absl/base:raw_logging_internal", + "//absl/log", "//absl/types:optional", "@com_google_googletest//:gtest_main", ], diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index d2928bd7..9aaa7932 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt @@ -317,7 +317,7 @@ absl_cc_test( absl::core_headers absl::pow10_helper absl::config - absl::raw_logging_internal + absl::log absl::random_random absl::random_distributions absl::strings_internal @@ -372,9 +372,9 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS - absl::strings + absl::check absl::config - absl::raw_logging_internal + absl::strings GTest::gmock_main ) @@ -516,6 +516,7 @@ absl_cc_test( absl::strings absl::str_format_internal absl::core_headers + absl::log absl::raw_logging_internal absl::int128 GTest::gmock_main @@ -960,19 +961,20 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS - absl::cord - absl::str_format - absl::strings absl::base + absl::check absl::config + absl::cord absl::cord_test_helpers absl::cordz_test_helpers absl::core_headers absl::endian + absl::fixed_array absl::hash + absl::log absl::random_random - absl::raw_logging_internal - absl::fixed_array + absl::str_format + absl::strings GTest::gmock_main ) diff --git a/absl/strings/charconv.cc b/absl/strings/charconv.cc index c510aea4..778a1c75 100644 --- a/absl/strings/charconv.cc +++ b/absl/strings/charconv.cc @@ -21,6 +21,7 @@ #include <limits> #include "absl/base/casts.h" +#include "absl/base/config.h" #include "absl/numeric/bits.h" #include "absl/numeric/int128.h" #include "absl/strings/internal/charconv_bigint.h" @@ -118,10 +119,17 @@ struct FloatTraits<double> { static constexpr int kEiselLemireMaxExclusiveExp10 = 309; static double MakeNan(const char* tagp) { +#if ABSL_HAVE_BUILTIN(__builtin_nan) + // Use __builtin_nan() if available since it has a fix for + // https://bugs.llvm.org/show_bug.cgi?id=37778 + // std::nan may use the glibc implementation. + return __builtin_nan(tagp); +#else // Support nan no matter which namespace it's in. Some platforms // incorrectly don't put it in namespace std. using namespace std; // NOLINT return nan(tagp); +#endif } // Builds a nonzero floating point number out of the provided parts. @@ -184,10 +192,17 @@ struct FloatTraits<float> { static constexpr int kEiselLemireMaxExclusiveExp10 = 39; static float MakeNan(const char* tagp) { +#if ABSL_HAVE_BUILTIN(__builtin_nanf) + // Use __builtin_nanf() if available since it has a fix for + // https://bugs.llvm.org/show_bug.cgi?id=37778 + // std::nanf may use the glibc implementation. + return __builtin_nanf(tagp); +#else // Support nanf no matter which namespace it's in. Some platforms // incorrectly don't put it in namespace std. using namespace std; // NOLINT - return nanf(tagp); + return std::nanf(tagp); +#endif } static float Make(mantissa_t mantissa, int exponent, bool sign) { @@ -350,7 +365,8 @@ bool HandleEdgeCase(const strings_internal::ParsedFloat& input, bool negative, // https://bugs.llvm.org/show_bug.cgi?id=37778 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86113 constexpr ptrdiff_t kNanBufferSize = 128; -#if defined(__GNUC__) || (defined(__clang__) && __clang_major__ < 7) +#if (defined(__GNUC__) && !defined(__clang__)) || \ + (defined(__clang__) && __clang_major__ < 7) volatile char n_char_sequence[kNanBufferSize]; #else char n_char_sequence[kNanBufferSize]; diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc index 3fe3967f..55412c7f 100644 --- a/absl/strings/cord_test.cc +++ b/absl/strings/cord_test.cc @@ -30,10 +30,11 @@ #include "gtest/gtest.h" #include "absl/base/config.h" #include "absl/base/internal/endian.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" #include "absl/container/fixed_array.h" #include "absl/hash/hash.h" +#include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/random/random.h" #include "absl/strings/cord_test_helpers.h" #include "absl/strings/cordz_test_helpers.h" @@ -210,9 +211,8 @@ class CordTestPeer { } static Cord MakeSubstring(Cord src, size_t offset, size_t length) { - ABSL_RAW_CHECK(src.contents_.is_tree(), "Can not be inlined"); - ABSL_RAW_CHECK(src.ExpectedChecksum() == absl::nullopt, - "Can not be hardened"); + CHECK(src.contents_.is_tree()) << "Can not be inlined"; + CHECK(!src.ExpectedChecksum().has_value()) << "Can not be hardened"; Cord cord; auto* tree = cord_internal::SkipCrcNode(src.contents_.tree()); auto* rep = CordRepSubstring::Create(CordRep::Ref(tree), offset, length); @@ -374,7 +374,7 @@ TEST_P(CordTest, GigabyteCordFromExternal) { for (int i = 0; i < 1024; ++i) { c.Append(from); } - ABSL_RAW_LOG(INFO, "Made a Cord with %zu bytes!", c.size()); + LOG(INFO) << "Made a Cord with " << c.size() << " bytes!"; // Note: on a 32-bit build, this comes out to 2,818,048,000 bytes. // Note: on a 64-bit build, this comes out to 171,932,385,280 bytes. } @@ -1247,15 +1247,15 @@ absl::Cord BigCord(size_t len, char v) { // Splice block into cord. absl::Cord SpliceCord(const absl::Cord& blob, int64_t offset, const absl::Cord& block) { - ABSL_RAW_CHECK(offset >= 0, ""); - ABSL_RAW_CHECK(offset + block.size() <= blob.size(), ""); + CHECK_GE(offset, 0); + CHECK_LE(static_cast<size_t>(offset) + block.size(), blob.size()); absl::Cord result(blob); result.RemoveSuffix(blob.size() - offset); result.Append(block); absl::Cord suffix(blob); suffix.RemovePrefix(offset + block.size()); result.Append(suffix); - ABSL_RAW_CHECK(blob.size() == result.size(), ""); + CHECK_EQ(blob.size(), result.size()); return result; } @@ -1855,7 +1855,7 @@ TEST(CordTest, CordMemoryUsageBTree) { // windows DLL, we may have ODR like effects on the flag, meaning the DLL // code will run with the picked up default. if (!absl::CordTestPeer::Tree(cord1)->IsBtree()) { - ABSL_RAW_LOG(WARNING, "Cord library code not respecting btree flag"); + LOG(WARNING) << "Cord library code not respecting btree flag"; return; } @@ -1940,8 +1940,7 @@ TEST_P(CordTest, DiabolicalGrowth) { std::string value; absl::CopyCordToString(cord, &value); EXPECT_EQ(value, expected); - ABSL_RAW_LOG(INFO, "Diabolical size allocated = %zu", - cord.EstimatedMemoryUsage()); + LOG(INFO) << "Diabolical size allocated = " << cord.EstimatedMemoryUsage(); } // The following tests check support for >4GB cords in 64-bit binaries, and diff --git a/absl/strings/internal/charconv_parse_test.cc b/absl/strings/internal/charconv_parse_test.cc index bc2d1118..2b7b0821 100644 --- a/absl/strings/internal/charconv_parse_test.cc +++ b/absl/strings/internal/charconv_parse_test.cc @@ -19,7 +19,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/check.h" #include "absl/strings/str_cat.h" using absl::chars_format; @@ -56,14 +56,14 @@ void ExpectParsedFloat(std::string s, absl::chars_format format_flags, begin_subrange = static_cast<int>(open_bracket_pos); s.replace(open_bracket_pos, 1, ""); std::string::size_type close_bracket_pos = s.find(']'); - ABSL_RAW_CHECK(close_bracket_pos != absl::string_view::npos, - "Test input contains [ without matching ]"); + CHECK_NE(close_bracket_pos, absl::string_view::npos) + << "Test input contains [ without matching ]"; end_subrange = static_cast<int>(close_bracket_pos); s.replace(close_bracket_pos, 1, ""); } const std::string::size_type expected_characters_matched = s.find('$'); - ABSL_RAW_CHECK(expected_characters_matched != std::string::npos, - "Input string must contain $"); + CHECK_NE(expected_characters_matched, std::string::npos) + << "Input string must contain $"; s.replace(expected_characters_matched, 1, ""); ParsedFloat parsed = diff --git a/absl/strings/internal/cord_internal.cc b/absl/strings/internal/cord_internal.cc index b6b06cfa..b7874385 100644 --- a/absl/strings/internal/cord_internal.cc +++ b/absl/strings/internal/cord_internal.cc @@ -33,7 +33,6 @@ ABSL_CONST_INIT std::atomic<bool> cord_ring_buffer_enabled( kCordEnableRingBufferDefault); ABSL_CONST_INIT std::atomic<bool> shallow_subcords_enabled( kCordShallowSubcordsDefault); -ABSL_CONST_INIT std::atomic<bool> cord_btree_exhaustive_validation(false); void LogFatalNodeType(CordRep* rep) { ABSL_INTERNAL_LOG(FATAL, absl::StrCat("Unexpected node type: ", diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index e6f0d544..8d9836ba 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -69,12 +69,6 @@ enum CordFeatureDefaults { extern std::atomic<bool> cord_ring_buffer_enabled; extern std::atomic<bool> shallow_subcords_enabled; -// `cord_btree_exhaustive_validation` can be set to force exhaustive validation -// in debug assertions, and code that calls `IsValid()` explicitly. By default, -// assertions should be relatively cheap and AssertValid() can easily lead to -// O(n^2) complexity as recursive / full tree validation is O(n). -extern std::atomic<bool> cord_btree_exhaustive_validation; - inline void enable_cord_ring_buffer(bool enable) { cord_ring_buffer_enabled.store(enable, std::memory_order_relaxed); } diff --git a/absl/strings/internal/cord_rep_btree.cc b/absl/strings/internal/cord_rep_btree.cc index a86fdc0b..05bd0e20 100644 --- a/absl/strings/internal/cord_rep_btree.cc +++ b/absl/strings/internal/cord_rep_btree.cc @@ -14,6 +14,7 @@ #include "absl/strings/internal/cord_rep_btree.h" +#include <atomic> #include <cassert> #include <cstdint> #include <iostream> @@ -49,9 +50,7 @@ using CopyResult = CordRepBtree::CopyResult; constexpr auto kFront = CordRepBtree::kFront; constexpr auto kBack = CordRepBtree::kBack; -inline bool exhaustive_validation() { - return cord_btree_exhaustive_validation.load(std::memory_order_relaxed); -} +ABSL_CONST_INIT std::atomic<bool> cord_btree_exhaustive_validation(false); // Implementation of the various 'Dump' functions. // Prints the entire tree structure or 'rep'. External callers should @@ -362,6 +361,15 @@ struct StackOperations { } // namespace +void SetCordBtreeExhaustiveValidation(bool do_exaustive_validation) { + cord_btree_exhaustive_validation.store(do_exaustive_validation, + std::memory_order_relaxed); +} + +bool IsCordBtreeExhaustiveValidationEnabled() { + return cord_btree_exhaustive_validation.load(std::memory_order_relaxed); +} + void CordRepBtree::Dump(const CordRep* rep, absl::string_view label, bool include_contents, std::ostream& stream) { stream << "===================================\n"; @@ -450,7 +458,8 @@ bool CordRepBtree::IsValid(const CordRepBtree* tree, bool shallow) { child_length += edge->length; } NODE_CHECK_EQ(child_length, tree->length); - if ((!shallow || exhaustive_validation()) && tree->height() > 0) { + if ((!shallow || IsCordBtreeExhaustiveValidationEnabled()) && + tree->height() > 0) { for (CordRep* edge : tree->Edges()) { if (!IsValid(edge->btree(), shallow)) return false; } diff --git a/absl/strings/internal/cord_rep_btree.h b/absl/strings/internal/cord_rep_btree.h index 4209e512..be94b62e 100644 --- a/absl/strings/internal/cord_rep_btree.h +++ b/absl/strings/internal/cord_rep_btree.h @@ -32,6 +32,14 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace cord_internal { +// `SetCordBtreeExhaustiveValidation()` can be set to force exhaustive +// validation in debug assertions, and code that calls `IsValid()` +// explicitly. By default, assertions should be relatively cheap and +// AssertValid() can easily lead to O(n^2) complexity as recursive / full tree +// validation is O(n). +void SetCordBtreeExhaustiveValidation(bool do_exaustive_validation); +bool IsCordBtreeExhaustiveValidationEnabled(); + class CordRepBtreeNavigator; // CordRepBtree is as the name implies a btree implementation of a Cordrep tree. diff --git a/absl/strings/internal/cord_rep_btree_test.cc b/absl/strings/internal/cord_rep_btree_test.cc index 82aeca37..840acf9f 100644 --- a/absl/strings/internal/cord_rep_btree_test.cc +++ b/absl/strings/internal/cord_rep_btree_test.cc @@ -1355,9 +1355,9 @@ TEST(CordRepBtreeTest, AssertValid) { TEST(CordRepBtreeTest, CheckAssertValidShallowVsDeep) { // Restore exhaustive validation on any exit. - const bool exhaustive_validation = cord_btree_exhaustive_validation.load(); + const bool exhaustive_validation = IsCordBtreeExhaustiveValidationEnabled(); auto cleanup = absl::MakeCleanup([exhaustive_validation] { - cord_btree_exhaustive_validation.store(exhaustive_validation); + SetCordBtreeExhaustiveValidation(exhaustive_validation); }); // Create a tree of at least 2 levels, and mess with the original flat, which @@ -1372,7 +1372,7 @@ TEST(CordRepBtreeTest, CheckAssertValidShallowVsDeep) { } flat->length = 100; - cord_btree_exhaustive_validation.store(false); + SetCordBtreeExhaustiveValidation(false); EXPECT_FALSE(CordRepBtree::IsValid(tree)); EXPECT_TRUE(CordRepBtree::IsValid(tree, true)); EXPECT_FALSE(CordRepBtree::IsValid(tree, false)); @@ -1382,7 +1382,7 @@ TEST(CordRepBtreeTest, CheckAssertValidShallowVsDeep) { EXPECT_DEBUG_DEATH(CordRepBtree::AssertValid(tree, false), ".*"); #endif - cord_btree_exhaustive_validation.store(true); + SetCordBtreeExhaustiveValidation(true); EXPECT_FALSE(CordRepBtree::IsValid(tree)); EXPECT_FALSE(CordRepBtree::IsValid(tree, true)); EXPECT_FALSE(CordRepBtree::IsValid(tree, false)); diff --git a/absl/strings/internal/cord_rep_consume.cc b/absl/strings/internal/cord_rep_consume.cc index 20a55797..db7d4fef 100644 --- a/absl/strings/internal/cord_rep_consume.cc +++ b/absl/strings/internal/cord_rep_consume.cc @@ -42,7 +42,8 @@ CordRep* ClipSubstring(CordRepSubstring* substring) { } // namespace -void Consume(CordRep* rep, ConsumeFn consume_fn) { +void Consume(CordRep* rep, + FunctionRef<void(CordRep*, size_t, size_t)> consume_fn) { size_t offset = 0; size_t length = rep->length; @@ -53,8 +54,9 @@ void Consume(CordRep* rep, ConsumeFn consume_fn) { consume_fn(rep, offset, length); } -void ReverseConsume(CordRep* rep, ConsumeFn consume_fn) { - return Consume(rep, std::move(consume_fn)); +void ReverseConsume(CordRep* rep, + FunctionRef<void(CordRep*, size_t, size_t)> consume_fn) { + return Consume(rep, consume_fn); } } // namespace cord_internal diff --git a/absl/strings/internal/cord_rep_consume.h b/absl/strings/internal/cord_rep_consume.h index d46fca2b..bece1874 100644 --- a/absl/strings/internal/cord_rep_consume.h +++ b/absl/strings/internal/cord_rep_consume.h @@ -24,11 +24,6 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace cord_internal { -// Functor for the Consume() and ReverseConsume() functions: -// void ConsumeFunc(CordRep* rep, size_t offset, size_t length); -// See the Consume() and ReverseConsume() function comments for documentation. -using ConsumeFn = FunctionRef<void(CordRep*, size_t, size_t)>; - // Consume() and ReverseConsume() consume CONCAT based trees and invoke the // provided functor with the contained nodes in the proper forward or reverse // order, which is used to convert CONCAT trees into other tree or cord data. @@ -40,8 +35,10 @@ using ConsumeFn = FunctionRef<void(CordRep*, size_t, size_t)>; // violations, we can not 100% guarantee that all code respects 'new format' // settings and flags, so we need to be able to parse old data on the fly until // all old code is deprecated / no longer the default format. -void Consume(CordRep* rep, ConsumeFn consume_fn); -void ReverseConsume(CordRep* rep, ConsumeFn consume_fn); +void Consume(CordRep* rep, + FunctionRef<void(CordRep*, size_t, size_t)> consume_fn); +void ReverseConsume(CordRep* rep, + FunctionRef<void(CordRep*, size_t, size_t)> consume_fn); } // namespace cord_internal ABSL_NAMESPACE_END diff --git a/absl/strings/internal/cord_rep_flat.h b/absl/strings/internal/cord_rep_flat.h index e3e27fcd..27c4b21e 100644 --- a/absl/strings/internal/cord_rep_flat.h +++ b/absl/strings/internal/cord_rep_flat.h @@ -120,8 +120,16 @@ struct CordRepFlat : public CordRep { // Round size up so it matches a size we can exactly express in a tag. const size_t size = RoundUpForTag(len + kFlatOverhead); void* const raw_rep = ::operator new(size); + // GCC 13 has a false-positive -Wstringop-overflow warning here. + #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(13, 0) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstringop-overflow" + #endif CordRepFlat* rep = new (raw_rep) CordRepFlat(); rep->tag = AllocatedSizeToTag(size); + #if ABSL_INTERNAL_HAVE_MIN_GNUC_VERSION(13, 0) + #pragma GCC diagnostic pop + #endif return rep; } diff --git a/absl/strings/internal/cordz_handle.cc b/absl/strings/internal/cordz_handle.cc index a73fefed..a7061dbe 100644 --- a/absl/strings/internal/cordz_handle.cc +++ b/absl/strings/internal/cordz_handle.cc @@ -16,34 +16,60 @@ #include <atomic> #include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK -#include "absl/base/internal/spinlock.h" +#include "absl/synchronization/mutex.h" namespace absl { ABSL_NAMESPACE_BEGIN namespace cord_internal { -using ::absl::base_internal::SpinLockHolder; +namespace { -ABSL_CONST_INIT CordzHandle::Queue CordzHandle::global_queue_(absl::kConstInit); +struct Queue { + Queue() = default; + + absl::Mutex mutex; + std::atomic<CordzHandle*> dq_tail ABSL_GUARDED_BY(mutex){nullptr}; + + // Returns true if this delete queue is empty. This method does not acquire + // the lock, but does a 'load acquire' observation on the delete queue tail. + // It is used inside Delete() to check for the presence of a delete queue + // without holding the lock. The assumption is that the caller is in the + // state of 'being deleted', and can not be newly discovered by a concurrent + // 'being constructed' snapshot instance. Practically, this means that any + // such discovery (`find`, 'first' or 'next', etc) must have proper 'happens + // before / after' semantics and atomic fences. + bool IsEmpty() const ABSL_NO_THREAD_SAFETY_ANALYSIS { + return dq_tail.load(std::memory_order_acquire) == nullptr; + } +}; + +static Queue* GlobalQueue() { + static Queue* global_queue = new Queue; + return global_queue; +} + +} // namespace CordzHandle::CordzHandle(bool is_snapshot) : is_snapshot_(is_snapshot) { + Queue* global_queue = GlobalQueue(); if (is_snapshot) { - SpinLockHolder lock(&queue_->mutex); - CordzHandle* dq_tail = queue_->dq_tail.load(std::memory_order_acquire); + MutexLock lock(&global_queue->mutex); + CordzHandle* dq_tail = + global_queue->dq_tail.load(std::memory_order_acquire); if (dq_tail != nullptr) { dq_prev_ = dq_tail; dq_tail->dq_next_ = this; } - queue_->dq_tail.store(this, std::memory_order_release); + global_queue->dq_tail.store(this, std::memory_order_release); } } CordzHandle::~CordzHandle() { - ODRCheck(); + Queue* global_queue = GlobalQueue(); if (is_snapshot_) { std::vector<CordzHandle*> to_delete; { - SpinLockHolder lock(&queue_->mutex); + MutexLock lock(&global_queue->mutex); CordzHandle* next = dq_next_; if (dq_prev_ == nullptr) { // We were head of the queue, delete every CordzHandle until we reach @@ -59,7 +85,7 @@ CordzHandle::~CordzHandle() { if (next) { next->dq_prev_ = dq_prev_; } else { - queue_->dq_tail.store(dq_prev_, std::memory_order_release); + global_queue->dq_tail.store(dq_prev_, std::memory_order_release); } } for (CordzHandle* handle : to_delete) { @@ -69,16 +95,15 @@ CordzHandle::~CordzHandle() { } bool CordzHandle::SafeToDelete() const { - return is_snapshot_ || queue_->IsEmpty(); + return is_snapshot_ || GlobalQueue()->IsEmpty(); } void CordzHandle::Delete(CordzHandle* handle) { assert(handle); if (handle) { - handle->ODRCheck(); - Queue* const queue = handle->queue_; + Queue* const queue = GlobalQueue(); if (!handle->SafeToDelete()) { - SpinLockHolder lock(&queue->mutex); + MutexLock lock(&queue->mutex); CordzHandle* dq_tail = queue->dq_tail.load(std::memory_order_acquire); if (dq_tail != nullptr) { handle->dq_prev_ = dq_tail; @@ -93,8 +118,9 @@ void CordzHandle::Delete(CordzHandle* handle) { std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { std::vector<const CordzHandle*> handles; - SpinLockHolder lock(&global_queue_.mutex); - CordzHandle* dq_tail = global_queue_.dq_tail.load(std::memory_order_acquire); + Queue* global_queue = GlobalQueue(); + MutexLock lock(&global_queue->mutex); + CordzHandle* dq_tail = global_queue->dq_tail.load(std::memory_order_acquire); for (const CordzHandle* p = dq_tail; p; p = p->dq_prev_) { handles.push_back(p); } @@ -103,13 +129,13 @@ std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetDeleteQueue() { bool CordzHandle::DiagnosticsHandleIsSafeToInspect( const CordzHandle* handle) const { - ODRCheck(); if (!is_snapshot_) return false; if (handle == nullptr) return true; if (handle->is_snapshot_) return false; bool snapshot_found = false; - SpinLockHolder lock(&queue_->mutex); - for (const CordzHandle* p = queue_->dq_tail; p; p = p->dq_prev_) { + Queue* global_queue = GlobalQueue(); + MutexLock lock(&global_queue->mutex); + for (const CordzHandle* p = global_queue->dq_tail; p; p = p->dq_prev_) { if (p == handle) return !snapshot_found; if (p == this) snapshot_found = true; } @@ -119,13 +145,13 @@ bool CordzHandle::DiagnosticsHandleIsSafeToInspect( std::vector<const CordzHandle*> CordzHandle::DiagnosticsGetSafeToInspectDeletedHandles() { - ODRCheck(); std::vector<const CordzHandle*> handles; if (!is_snapshot()) { return handles; } - SpinLockHolder lock(&queue_->mutex); + Queue* global_queue = GlobalQueue(); + MutexLock lock(&global_queue->mutex); for (const CordzHandle* p = dq_next_; p != nullptr; p = p->dq_next_) { if (!p->is_snapshot()) { handles.push_back(p); diff --git a/absl/strings/internal/cordz_handle.h b/absl/strings/internal/cordz_handle.h index 3c800b43..08e3f0d3 100644 --- a/absl/strings/internal/cordz_handle.h +++ b/absl/strings/internal/cordz_handle.h @@ -20,8 +20,6 @@ #include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/spinlock.h" -#include "absl/synchronization/mutex.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -34,7 +32,7 @@ namespace cord_internal { // has gained visibility into a CordzInfo object, that CordzInfo object will not // be deleted prematurely. This allows the profiler to inspect all CordzInfo // objects that are alive without needing to hold a global lock. -class CordzHandle { +class ABSL_DLL CordzHandle { public: CordzHandle() : CordzHandle(false) {} @@ -79,37 +77,6 @@ class CordzHandle { virtual ~CordzHandle(); private: - // Global queue data. CordzHandle stores a pointer to the global queue - // instance to harden against ODR violations. - struct Queue { - constexpr explicit Queue(absl::ConstInitType) - : mutex(absl::kConstInit, - absl::base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL) {} - - absl::base_internal::SpinLock mutex; - std::atomic<CordzHandle*> dq_tail ABSL_GUARDED_BY(mutex){nullptr}; - - // Returns true if this delete queue is empty. This method does not acquire - // the lock, but does a 'load acquire' observation on the delete queue tail. - // It is used inside Delete() to check for the presence of a delete queue - // without holding the lock. The assumption is that the caller is in the - // state of 'being deleted', and can not be newly discovered by a concurrent - // 'being constructed' snapshot instance. Practically, this means that any - // such discovery (`find`, 'first' or 'next', etc) must have proper 'happens - // before / after' semantics and atomic fences. - bool IsEmpty() const ABSL_NO_THREAD_SAFETY_ANALYSIS { - return dq_tail.load(std::memory_order_acquire) == nullptr; - } - }; - - void ODRCheck() const { -#ifndef NDEBUG - ABSL_RAW_CHECK(queue_ == &global_queue_, "ODR violation in Cord"); -#endif - } - - ABSL_CONST_INIT static Queue global_queue_; - Queue* const queue_ = &global_queue_; const bool is_snapshot_; // dq_prev_ and dq_next_ require the global queue mutex to be held. diff --git a/absl/strings/internal/str_format/convert_test.cc b/absl/strings/internal/str_format/convert_test.cc index 8b5a27ed..16ff9879 100644 --- a/absl/strings/internal/str_format/convert_test.cc +++ b/absl/strings/internal/str_format/convert_test.cc @@ -26,6 +26,7 @@ #include "gtest/gtest.h" #include "absl/base/attributes.h" #include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/strings/internal/str_format/bind.h" #include "absl/strings/match.h" #include "absl/types/optional.h" @@ -264,7 +265,7 @@ MATCHER_P(MatchesPointerString, ptr, "") { } void* parsed = nullptr; if (sscanf(arg.c_str(), "%p", &parsed) != 1) { - ABSL_RAW_LOG(FATAL, "Could not parse %s", arg.c_str()); + LOG(FATAL) << "Could not parse " << arg; } return ptr == parsed; } diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index c2b861ae..7dc89224 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc @@ -31,7 +31,9 @@ #include <utility> #include "absl/base/attributes.h" +#include "absl/base/internal/endian.h" #include "absl/base/internal/raw_logging.h" +#include "absl/base/optimization.h" #include "absl/numeric/bits.h" #include "absl/strings/ascii.h" #include "absl/strings/charconv.h" @@ -136,82 +138,123 @@ bool SimpleAtob(absl::string_view str, bool* out) { namespace { -// Used to optimize printing a decimal number's final digit. -const char one_ASCII_final_digits[10][2] { - {'0', 0}, {'1', 0}, {'2', 0}, {'3', 0}, {'4', 0}, - {'5', 0}, {'6', 0}, {'7', 0}, {'8', 0}, {'9', 0}, -}; +// Various routines to encode integers to strings. + +// We split data encodings into a group of 2 digits, 4 digits, 8 digits as +// it's easier to combine powers of two into scalar arithmetic. + +// Previous implementation used a lookup table of 200 bytes for every 2 bytes +// and it was memory bound, any L1 cache miss would result in a much slower +// result. When benchmarking with a cache eviction rate of several percent, +// this implementation proved to be better. + +// These constants represent '00', '0000' and '00000000' as ascii strings in +// integers. We can add these numbers if we encode to bytes from 0 to 9. as +// 'i' = '0' + i for 0 <= i <= 9. +constexpr uint32_t kTwoZeroBytes = 0x0101 * '0'; +constexpr uint64_t kFourZeroBytes = 0x01010101 * '0'; +constexpr uint64_t kEightZeroBytes = 0x0101010101010101ull * '0'; + +// * 103 / 1024 is a division by 10 for values from 0 to 99. It's also a +// division of a structure [k takes 2 bytes][m takes 2 bytes], then * 103 / 1024 +// will be [k / 10][m / 10]. It allows parallel division. +constexpr uint64_t kDivisionBy10Mul = 103u; +constexpr uint64_t kDivisionBy10Div = 1 << 10; + +// * 10486 / 1048576 is a division by 100 for values from 0 to 9999. +constexpr uint64_t kDivisionBy100Mul = 10486u; +constexpr uint64_t kDivisionBy100Div = 1 << 20; + +// Encode functions write the ASCII output of input `n` to `out_str`. +inline char* EncodeHundred(uint32_t n, char* out_str) { + int num_digits = static_cast<int>(n - 10) >> 8; + uint32_t base = kTwoZeroBytes; + uint32_t div10 = (n * kDivisionBy10Mul) / kDivisionBy10Div; + uint32_t mod10 = n - 10u * div10; + base += div10 + (mod10 << 8); + base >>= num_digits & 8; + little_endian::Store16(out_str, static_cast<uint16_t>(base)); + return out_str + 2 + num_digits; +} -} // namespace +inline char* EncodeTenThousand(uint32_t n, char* out_str) { + // We split lower 2 digits and upper 2 digits of n into 2 byte consecutive + // blocks. 123 -> [\0\1][\0\23]. We divide by 10 both blocks + // (it's 1 division + zeroing upper bits), and compute modulo 10 as well "in + // parallel". Then we combine both results to have both ASCII digits, + // strip trailing zeros, add ASCII '0000' and return. + uint32_t div100 = (n * kDivisionBy100Mul) / kDivisionBy100Div; + uint32_t mod100 = n - 100ull * div100; + uint32_t hundreds = (mod100 << 16) + div100; + uint32_t tens = (hundreds * kDivisionBy10Mul) / kDivisionBy10Div; + tens &= (0xFull << 16) | 0xFull; + tens += (hundreds - 10ull * tens) << 8; + ABSL_ASSUME(tens != 0); + // The result can contain trailing zero bits, we need to strip them to a first + // significant byte in a final representation. For example, for n = 123, we + // have tens to have representation \0\1\2\3. We do `& -8` to round + // to a multiple to 8 to strip zero bytes, not all zero bits. + // countr_zero to help. + // 0 minus 8 to make MSVC happy. + uint32_t zeroes = static_cast<uint32_t>(absl::countr_zero(tens)) & (0 - 8ull); + tens += kFourZeroBytes; + tens >>= zeroes; + little_endian::Store32(out_str, tens); + return out_str + sizeof(tens) - zeroes / 8; +} -char* numbers_internal::FastIntToBuffer(uint32_t i, char* buffer) { - uint32_t digits; - // The idea of this implementation is to trim the number of divides to as few - // as possible, and also reducing memory stores and branches, by going in - // steps of two digits at a time rather than one whenever possible. - // The huge-number case is first, in the hopes that the compiler will output - // that case in one branch-free block of code, and only output conditional - // branches into it from below. - if (i >= 1000000000) { // >= 1,000,000,000 - digits = i / 100000000; // 100,000,000 - i -= digits * 100000000; - PutTwoDigits(digits, buffer); - buffer += 2; - lt100_000_000: - digits = i / 1000000; // 1,000,000 - i -= digits * 1000000; - PutTwoDigits(digits, buffer); - buffer += 2; - lt1_000_000: - digits = i / 10000; // 10,000 - i -= digits * 10000; - PutTwoDigits(digits, buffer); - buffer += 2; - lt10_000: - digits = i / 100; - i -= digits * 100; - PutTwoDigits(digits, buffer); - buffer += 2; - lt100: - digits = i; - PutTwoDigits(digits, buffer); - buffer += 2; - *buffer = 0; - return buffer; - } +// Prepare functions return an integer that should be written to out_str +// (but possibly include trailing zeros). +// For hi < 10000, lo < 10000 returns uint64_t as encoded in ASCII with +// possibly trailing zeroes of the number hi * 10000 + lo. +inline uint64_t PrepareTenThousands(uint64_t hi, uint64_t lo) { + uint64_t merged = hi | (lo << 32); + uint64_t div100 = ((merged * kDivisionBy100Mul) / kDivisionBy100Div) & + ((0x7Full << 32) | 0x7Full); + uint64_t mod100 = merged - 100ull * div100; + uint64_t hundreds = (mod100 << 16) + div100; + uint64_t tens = (hundreds * kDivisionBy10Mul) / kDivisionBy10Div; + tens &= (0xFull << 48) | (0xFull << 32) | (0xFull << 16) | 0xFull; + tens += (hundreds - 10ull * tens) << 8; + return tens; +} - if (i < 100) { - digits = i; - if (i >= 10) goto lt100; - memcpy(buffer, one_ASCII_final_digits[i], 2); - return buffer + 1; - } - if (i < 10000) { // 10,000 - if (i >= 1000) goto lt10_000; - digits = i / 100; - i -= digits * 100; - *buffer++ = '0' + static_cast<char>(digits); - goto lt100; +inline char* EncodeFullU32(uint32_t n, char* out_str) { + if (n < 100'000'000) { + uint64_t bottom = PrepareTenThousands(n / 10000, n % 10000); + ABSL_ASSUME(bottom != 0); + // 0 minus 8 to make MSVC happy. + uint32_t zeroes = static_cast<uint32_t>(absl::countr_zero(bottom)) + & (0 - 8ull); + uint64_t bottom_res = bottom + kEightZeroBytes; + bottom_res >>= zeroes; + little_endian::Store64(out_str, bottom_res); + return out_str + sizeof(bottom) - zeroes / 8; } - if (i < 1000000) { // 1,000,000 - if (i >= 100000) goto lt1_000_000; - digits = i / 10000; // 10,000 - i -= digits * 10000; - *buffer++ = '0' + static_cast<char>(digits); - goto lt10_000; + uint32_t top = n / 100'000'000; + n %= 100'000'000; + uint64_t bottom = PrepareTenThousands(n / 10000, n % 10000); + uint64_t bottom_res = bottom + kEightZeroBytes; + out_str = EncodeHundred(top, out_str); + little_endian::Store64(out_str, bottom_res); + return out_str + sizeof(bottom); +} + +} // namespace + +char* numbers_internal::FastIntToBuffer(uint32_t n, char* out_str) { + if (n < 100) { + out_str = EncodeHundred(n, out_str); + goto set_last_zero; } - if (i < 100000000) { // 100,000,000 - if (i >= 10000000) goto lt100_000_000; - digits = i / 1000000; // 1,000,000 - i -= digits * 1000000; - *buffer++ = '0' + static_cast<char>(digits); - goto lt1_000_000; + if (n < 10000) { + out_str = EncodeTenThousand(n, out_str); + goto set_last_zero; } - // we already know that i < 1,000,000,000 - digits = i / 100000000; // 100,000,000 - i -= digits * 100000000; - *buffer++ = '0' + static_cast<char>(digits); - goto lt100_000_000; + out_str = EncodeFullU32(n, out_str); +set_last_zero: + *out_str = '\0'; + return out_str; } char* numbers_internal::FastIntToBuffer(int32_t i, char* buffer) { @@ -230,41 +273,40 @@ char* numbers_internal::FastIntToBuffer(uint64_t i, char* buffer) { uint32_t u32 = static_cast<uint32_t>(i); if (u32 == i) return numbers_internal::FastIntToBuffer(u32, buffer); - // Here we know i has at least 10 decimal digits. - uint64_t top_1to11 = i / 1000000000; - u32 = static_cast<uint32_t>(i - top_1to11 * 1000000000); - uint32_t top_1to11_32 = static_cast<uint32_t>(top_1to11); + // 10**9 < 2**32 <= i < 10**10, we can do 2+8 + uint64_t div08 = i / 100'000'000ull; + uint64_t mod08 = i % 100'000'000ull; + uint64_t mod_result = + PrepareTenThousands(mod08 / 10000, mod08 % 10000) + kEightZeroBytes; + if (i < 10'000'000'000ull) { + buffer = EncodeHundred(static_cast<uint32_t>(div08), buffer); + little_endian::Store64(buffer, mod_result); + buffer += 8; + goto set_last_zero; + } - if (top_1to11_32 == top_1to11) { - buffer = numbers_internal::FastIntToBuffer(top_1to11_32, buffer); + // i < 10**16, in this case 8+8 + if (i < 10'000'000'000'000'000ull) { + buffer = EncodeFullU32(static_cast<uint32_t>(div08), buffer); + little_endian::Store64(buffer, mod_result); + buffer += 8; + goto set_last_zero; } else { - // top_1to11 has more than 32 bits too; print it in two steps. - uint32_t top_8to9 = static_cast<uint32_t>(top_1to11 / 100); - uint32_t mid_2 = static_cast<uint32_t>(top_1to11 - top_8to9 * 100); - buffer = numbers_internal::FastIntToBuffer(top_8to9, buffer); - PutTwoDigits(mid_2, buffer); - buffer += 2; + // 4 + 8 + 8 + uint64_t div016 = i / 10'000'000'000'000'000ull; + buffer = EncodeTenThousand(static_cast<uint32_t>(div016), buffer); + uint64_t mid_result = div08 - div016 * 100'000'000ull; + mid_result = PrepareTenThousands(mid_result / 10000, mid_result % 10000) + + kEightZeroBytes; + little_endian::Store64(buffer, mid_result); + buffer += 8; + little_endian::Store64(buffer, mod_result); + buffer += 8; + goto set_last_zero; } - - // We have only 9 digits now, again the maximum uint32_t can handle fully. - uint32_t digits = u32 / 10000000; // 10,000,000 - u32 -= digits * 10000000; - PutTwoDigits(digits, buffer); - buffer += 2; - digits = u32 / 100000; // 100,000 - u32 -= digits * 100000; - PutTwoDigits(digits, buffer); - buffer += 2; - digits = u32 / 1000; // 1,000 - u32 -= digits * 1000; - PutTwoDigits(digits, buffer); - buffer += 2; - digits = u32 / 10; - u32 -= digits * 10; - PutTwoDigits(digits, buffer); - buffer += 2; - memcpy(buffer, one_ASCII_final_digits[u32], 2); - return buffer + 1; +set_last_zero: + *buffer = '\0'; + return buffer; } char* numbers_internal::FastIntToBuffer(int64_t i, char* buffer) { diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc index b3c098d1..2864bda2 100644 --- a/absl/strings/numbers_test.cc +++ b/absl/strings/numbers_test.cc @@ -37,7 +37,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/random/distributions.h" #include "absl/random/random.h" #include "absl/strings/internal/numbers_test_common.h" @@ -1337,11 +1337,9 @@ TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) { if (strcmp(sixdigitsbuf, snprintfbuf) != 0) { mismatches.push_back(d); if (mismatches.size() < 10) { - ABSL_RAW_LOG(ERROR, "%s", - absl::StrCat("Six-digit failure with double. ", "d=", d, - "=", d, " sixdigits=", sixdigitsbuf, - " printf(%g)=", snprintfbuf) - .c_str()); + LOG(ERROR) << "Six-digit failure with double. d=" << d + << " sixdigits=" << sixdigitsbuf + << " printf(%g)=" << snprintfbuf; } } }; @@ -1389,12 +1387,10 @@ TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) { if (kFloatNumCases >= 1e9) { // The exhaustive test takes a very long time, so log progress. char buf[kSixDigitsToBufferSize]; - ABSL_RAW_LOG( - INFO, "%s", - absl::StrCat("Exp ", exponent, " powten=", powten, "(", powten, - ") (", - std::string(buf, SixDigitsToBuffer(powten, buf)), ")") - .c_str()); + LOG(INFO) << "Exp " << exponent << " powten=" << powten << "(" << powten + << ") (" + << absl::string_view(buf, SixDigitsToBuffer(powten, buf)) + << ")"; } for (int digits : digit_testcases) { if (exponent == 308 && digits >= 179769) break; // don't overflow! @@ -1419,20 +1415,17 @@ TEST_F(SimpleDtoaTest, ExhaustiveDoubleToSixDigits) { double before = nextafter(d, 0.0); double after = nextafter(d, 1.7976931348623157e308); char b1[32], b2[kSixDigitsToBufferSize]; - ABSL_RAW_LOG( - ERROR, "%s", - absl::StrCat( - "Mismatch #", i, " d=", d, " (", ToNineDigits(d), ")", - " sixdigits='", sixdigitsbuf, "'", " snprintf='", snprintfbuf, - "'", " Before.=", PerfectDtoa(before), " ", - (SixDigitsToBuffer(before, b2), b2), - " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", before), b1), - " Perfect=", PerfectDtoa(d), " ", (SixDigitsToBuffer(d, b2), b2), - " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", d), b1), - " After.=.", PerfectDtoa(after), " ", - (SixDigitsToBuffer(after, b2), b2), - " vs snprintf=", (snprintf(b1, sizeof(b1), "%g", after), b1)) - .c_str()); + LOG(ERROR) << "Mismatch #" << i << " d=" << d << " (" << ToNineDigits(d) + << ") sixdigits='" << sixdigitsbuf << "' snprintf='" + << snprintfbuf << "' Before.=" << PerfectDtoa(before) << " " + << (SixDigitsToBuffer(before, b2), b2) << " vs snprintf=" + << (snprintf(b1, sizeof(b1), "%g", before), b1) + << " Perfect=" << PerfectDtoa(d) << " " + << (SixDigitsToBuffer(d, b2), b2) + << " vs snprintf=" << (snprintf(b1, sizeof(b1), "%g", d), b1) + << " After.=." << PerfectDtoa(after) << " " + << (SixDigitsToBuffer(after, b2), b2) << " vs snprintf=" + << (snprintf(b1, sizeof(b1), "%g", after), b1); } } } diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index a0cd433d..3d405df8 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel @@ -198,7 +198,8 @@ cc_test( deps = [ ":graphcycles_internal", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log", + "//absl/log:check", "@com_google_googletest//:gtest_main", ], ) @@ -238,6 +239,7 @@ cc_test( size = "large", srcs = ["mutex_test.cc"], copts = ABSL_TEST_COPTS, + flaky = 1, linkopts = ABSL_DEFAULT_LINKOPTS, shard_count = 25, deps = [ @@ -246,7 +248,8 @@ cc_test( "//absl/base", "//absl/base:config", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log", + "//absl/log:check", "//absl/memory", "//absl/time", "@com_google_googletest//:gtest_main", @@ -300,6 +303,7 @@ cc_test( size = "small", srcs = ["notification_test.cc"], copts = ABSL_TEST_COPTS, + flaky = 1, linkopts = ABSL_DEFAULT_LINKOPTS, tags = ["no_test_lexan"], deps = [ @@ -374,6 +378,6 @@ cc_test( deps = [ ":synchronization", "//absl/base:core_headers", - "//absl/base:raw_logging_internal", + "//absl/log:check", ], ) diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index 86278349..a0f64e5c 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt @@ -151,9 +151,10 @@ absl_cc_test( COPTS ${ABSL_TEST_COPTS} DEPS - absl::graphcycles_internal + absl::check absl::core_headers - absl::raw_logging_internal + absl::graphcycles_internal + absl::log GTest::gmock_main ) @@ -183,10 +184,11 @@ absl_cc_test( absl::synchronization absl::thread_pool absl::base + absl::check absl::config absl::core_headers + absl::log absl::memory - absl::raw_logging_internal absl::time GTest::gmock_main ) @@ -278,5 +280,5 @@ absl_cc_test( DEPS absl::synchronization absl::core_headers - absl::raw_logging_internal + absl::check ) diff --git a/absl/synchronization/internal/futex_waiter.cc b/absl/synchronization/internal/futex_waiter.cc index 7c07fbe2..87eb3b23 100644 --- a/absl/synchronization/internal/futex_waiter.cc +++ b/absl/synchronization/internal/futex_waiter.cc @@ -63,7 +63,6 @@ bool FutexWaiter::Wait(KernelTimeout t) { // Note that, since the thread ticker is just reset, we don't need to check // whether the thread is idle on the very first pass of the loop. bool first_pass = true; - while (true) { int32_t x = futex_.load(std::memory_order_relaxed); while (x != 0) { diff --git a/absl/synchronization/internal/graphcycles_test.cc b/absl/synchronization/internal/graphcycles_test.cc index 74eaffe7..3c6ef798 100644 --- a/absl/synchronization/internal/graphcycles_test.cc +++ b/absl/synchronization/internal/graphcycles_test.cc @@ -21,8 +21,9 @@ #include <vector> #include "gtest/gtest.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/macros.h" +#include "absl/log/check.h" +#include "absl/log/log.h" namespace absl { ABSL_NAMESPACE_BEGIN @@ -65,51 +66,51 @@ static bool IsReachable(Edges *edges, int from, int to, } static void PrintEdges(Edges *edges) { - ABSL_RAW_LOG(INFO, "EDGES (%zu)", edges->size()); + LOG(INFO) << "EDGES (" << edges->size() << ")"; for (const auto &edge : *edges) { int a = edge.from; int b = edge.to; - ABSL_RAW_LOG(INFO, "%d %d", a, b); + LOG(INFO) << a << " " << b; } - ABSL_RAW_LOG(INFO, "---"); + LOG(INFO) << "---"; } static void PrintGCEdges(Nodes *nodes, const IdMap &id, GraphCycles *gc) { - ABSL_RAW_LOG(INFO, "GC EDGES"); + LOG(INFO) << "GC EDGES"; for (int a : *nodes) { for (int b : *nodes) { if (gc->HasEdge(Get(id, a), Get(id, b))) { - ABSL_RAW_LOG(INFO, "%d %d", a, b); + LOG(INFO) << a << " " << b; } } } - ABSL_RAW_LOG(INFO, "---"); + LOG(INFO) << "---"; } static void PrintTransitiveClosure(Nodes *nodes, Edges *edges) { - ABSL_RAW_LOG(INFO, "Transitive closure"); + LOG(INFO) << "Transitive closure"; for (int a : *nodes) { for (int b : *nodes) { std::unordered_set<int> seen; if (IsReachable(edges, a, b, &seen)) { - ABSL_RAW_LOG(INFO, "%d %d", a, b); + LOG(INFO) << a << " " << b; } } } - ABSL_RAW_LOG(INFO, "---"); + LOG(INFO) << "---"; } static void PrintGCTransitiveClosure(Nodes *nodes, const IdMap &id, GraphCycles *gc) { - ABSL_RAW_LOG(INFO, "GC Transitive closure"); + LOG(INFO) << "GC Transitive closure"; for (int a : *nodes) { for (int b : *nodes) { if (gc->IsReachable(Get(id, a), Get(id, b))) { - ABSL_RAW_LOG(INFO, "%d %d", a, b); + LOG(INFO) << a << " " << b; } } } - ABSL_RAW_LOG(INFO, "---"); + LOG(INFO) << "---"; } static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id, @@ -125,9 +126,8 @@ static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id, PrintGCEdges(nodes, id, gc); PrintTransitiveClosure(nodes, edges); PrintGCTransitiveClosure(nodes, id, gc); - ABSL_RAW_LOG(FATAL, "gc_reachable %s reachable %s a %d b %d", - gc_reachable ? "true" : "false", - reachable ? "true" : "false", a, b); + LOG(FATAL) << "gc_reachable " << gc_reachable << " reachable " + << reachable << " a " << a << " b " << b; } } } @@ -142,7 +142,7 @@ static void CheckEdges(Nodes *nodes, Edges *edges, const IdMap &id, if (!gc->HasEdge(Get(id, a), Get(id, b))) { PrintEdges(edges); PrintGCEdges(nodes, id, gc); - ABSL_RAW_LOG(FATAL, "!gc->HasEdge(%d, %d)", a, b); + LOG(FATAL) << "!gc->HasEdge(" << a << ", " << b << ")"; } } for (const auto &a : *nodes) { @@ -155,13 +155,12 @@ static void CheckEdges(Nodes *nodes, Edges *edges, const IdMap &id, if (count != edges->size()) { PrintEdges(edges); PrintGCEdges(nodes, id, gc); - ABSL_RAW_LOG(FATAL, "edges->size() %zu count %d", edges->size(), count); + LOG(FATAL) << "edges->size() " << edges->size() << " count " << count; } } static void CheckInvariants(const GraphCycles &gc) { - if (ABSL_PREDICT_FALSE(!gc.CheckInvariants())) - ABSL_RAW_LOG(FATAL, "CheckInvariants"); + CHECK(gc.CheckInvariants()) << "CheckInvariants"; } // Returns the index of a randomly chosen node in *nodes. @@ -309,7 +308,7 @@ TEST(GraphCycles, RandomizedTest) { break; default: - ABSL_RAW_LOG(FATAL, "op %d", op); + LOG(FATAL) << "op " << op; } // Very rarely, test graph expansion by adding then removing many nodes. diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index e6274232..d5ce35a1 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc @@ -18,8 +18,8 @@ #include "absl/base/attributes.h" #include "absl/base/const_init.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/thread_annotations.h" +#include "absl/log/check.h" #include "absl/synchronization/mutex.h" #include "absl/synchronization/notification.h" @@ -35,20 +35,20 @@ namespace { // Thread two waits on 'notification', then sets 'state' inside the 'mutex', // signalling the change via 'condvar'. // -// These tests use ABSL_RAW_CHECK to validate invariants, rather than EXPECT or -// ASSERT from gUnit, because we need to invoke them during global destructors, -// when gUnit teardown would have already begun. +// These tests use CHECK to validate invariants, rather than EXPECT or ASSERT +// from gUnit, because we need to invoke them during global destructors, when +// gUnit teardown would have already begun. void ThreadOne(absl::Mutex* mutex, absl::CondVar* condvar, absl::Notification* notification, bool* state) { // Test that the notification is in a valid initial state. - ABSL_RAW_CHECK(!notification->HasBeenNotified(), "invalid Notification"); - ABSL_RAW_CHECK(*state == false, "*state not initialized"); + CHECK(!notification->HasBeenNotified()) << "invalid Notification"; + CHECK(!*state) << "*state not initialized"; { absl::MutexLock lock(mutex); notification->Notify(); - ABSL_RAW_CHECK(notification->HasBeenNotified(), "invalid Notification"); + CHECK(notification->HasBeenNotified()) << "invalid Notification"; while (*state == false) { condvar->Wait(mutex); @@ -58,11 +58,11 @@ void ThreadOne(absl::Mutex* mutex, absl::CondVar* condvar, void ThreadTwo(absl::Mutex* mutex, absl::CondVar* condvar, absl::Notification* notification, bool* state) { - ABSL_RAW_CHECK(*state == false, "*state not initialized"); + CHECK(!*state) << "*state not initialized"; // Wake thread one notification->WaitForNotification(); - ABSL_RAW_CHECK(notification->HasBeenNotified(), "invalid Notification"); + CHECK(notification->HasBeenNotified()) << "invalid Notification"; { absl::MutexLock lock(mutex); *state = true; diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index a8911614..16a8fbff 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc @@ -103,9 +103,6 @@ ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<void (*)( ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<void (*)(const char *msg, const void *cv)> cond_var_tracer; -ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook< - bool (*)(const void *pc, char *out, int out_size)> - symbolizer(absl::Symbolize); } // namespace @@ -126,10 +123,6 @@ void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv)) { cond_var_tracer.Store(fn); } -void RegisterSymbolizer(bool (*fn)(const void *pc, char *out, int out_size)) { - symbolizer.Store(fn); -} - namespace { // Represents the strategy for spin and yield. // See the comment in GetMutexGlobals() for more information. @@ -1289,7 +1282,7 @@ static inline void DebugOnlyLockLeave(Mutex *mu) { static char *StackString(void **pcs, int n, char *buf, int maxlen, bool symbolize) { - static const int kSymLen = 200; + static constexpr int kSymLen = 200; char sym[kSymLen]; int len = 0; for (int i = 0; i != n; i++) { @@ -1297,7 +1290,7 @@ static char *StackString(void **pcs, int n, char *buf, int maxlen, return buf; size_t count = static_cast<size_t>(maxlen - len); if (symbolize) { - if (!symbolizer(pcs[i], sym, kSymLen)) { + if (!absl::Symbolize(pcs[i], sym, kSymLen)) { sym[0] = '\0'; } snprintf(buf + len, count, "%s\t@ %p %s\n", (i == 0 ? "\n" : ""), pcs[i], diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 8bbcae88..0b6a9e18 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h @@ -1105,23 +1105,6 @@ void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj, // RegisterMutexProfiler() above. void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv)); -// Register a hook for symbolizing stack traces in deadlock detector reports. -// -// '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 NUL-terminated symbol was written -// to 'out.' -// -// This has the same ordering and single-use limitations as -// RegisterMutexProfiler() above. -// -// DEPRECATED: The default symbolizer function is absl::Symbolize() and the -// ability to register a different hook for symbolizing stack traces will be -// removed on or after 2023-05-01. -ABSL_DEPRECATED("absl::RegisterSymbolizer() is deprecated and will be removed " - "on or after 2023-05-01") -void RegisterSymbolizer(bool (*fn)(const void *pc, char *out, int out_size)); - // EnableMutexInvariantDebugging() // // Enable or disable global support for Mutex invariant debugging. If enabled, diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc index ec039a70..4ae4d7e7 100644 --- a/absl/synchronization/mutex_test.cc +++ b/absl/synchronization/mutex_test.cc @@ -32,8 +32,9 @@ #include "gtest/gtest.h" #include "absl/base/attributes.h" #include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" #include "absl/base/internal/sysinfo.h" +#include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/synchronization/internal/thread_pool.h" #include "absl/time/clock.h" @@ -87,7 +88,7 @@ static void SetInvariantChecked(bool new_value) { static void CheckSumG0G1(void *v) { TestContext *cxt = static_cast<TestContext *>(v); - ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in CheckSumG0G1"); + CHECK_EQ(cxt->g0, -cxt->g1) << "Error in CheckSumG0G1"; SetInvariantChecked(true); } @@ -132,7 +133,7 @@ static void TestRW(TestContext *cxt, int c) { } else { for (int i = 0; i != cxt->iterations; i++) { absl::ReaderMutexLock l(&cxt->mu); - ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in TestRW"); + CHECK_EQ(cxt->g0, -cxt->g1) << "Error in TestRW"; cxt->mu.AssertReaderHeld(); } } @@ -157,7 +158,7 @@ static void TestAwait(TestContext *cxt, int c) { cxt->mu.AssertHeld(); while (cxt->g0 < cxt->iterations) { cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn)); - ABSL_RAW_CHECK(mc.MyTurn(), "Error in TestAwait"); + CHECK(mc.MyTurn()) << "Error in TestAwait"; cxt->mu.AssertHeld(); if (cxt->g0 < cxt->iterations) { int a = cxt->g0 + 1; @@ -185,7 +186,7 @@ static void TestSignalAll(TestContext *cxt, int c) { } static void TestSignal(TestContext *cxt, int c) { - ABSL_RAW_CHECK(cxt->threads == 2, "TestSignal should use 2 threads"); + CHECK_EQ(cxt->threads, 2) << "TestSignal should use 2 threads"; int target = c; absl::MutexLock l(&cxt->mu); cxt->mu.AssertHeld(); @@ -222,8 +223,8 @@ static void TestCVTimeout(TestContext *cxt, int c) { static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; } static void TestTime(TestContext *cxt, int c, bool use_cv) { - ABSL_RAW_CHECK(cxt->iterations == 1, "TestTime should only use 1 iteration"); - ABSL_RAW_CHECK(cxt->threads > 2, "TestTime should use more than 2 threads"); + CHECK_EQ(cxt->iterations, 1) << "TestTime should only use 1 iteration"; + CHECK_GT(cxt->threads, 2) << "TestTime should use more than 2 threads"; const bool kFalse = false; absl::Condition false_cond(&kFalse); absl::Condition g0ge2(G0GE2, cxt); @@ -234,26 +235,24 @@ static void TestTime(TestContext *cxt, int c, bool use_cv) { if (use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); } else { - ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), - "TestTime failed"); + CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1))) + << "TestTime failed"; } absl::Duration elapsed = absl::Now() - start; - ABSL_RAW_CHECK( - absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0), - "TestTime failed"); - ABSL_RAW_CHECK(cxt->g0 == 1, "TestTime failed"); + CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0)) + << "TestTime failed"; + CHECK_EQ(cxt->g0, 1) << "TestTime failed"; start = absl::Now(); if (use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); } else { - ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), - "TestTime failed"); + CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1))) + << "TestTime failed"; } elapsed = absl::Now() - start; - ABSL_RAW_CHECK( - absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0), - "TestTime failed"); + CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0)) + << "TestTime failed"; cxt->g0++; if (use_cv) { cxt->cv.Signal(); @@ -263,26 +262,24 @@ static void TestTime(TestContext *cxt, int c, bool use_cv) { if (use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4)); } else { - ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)), - "TestTime failed"); + CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4))) + << "TestTime failed"; } elapsed = absl::Now() - start; - ABSL_RAW_CHECK( - absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0), - "TestTime failed"); - ABSL_RAW_CHECK(cxt->g0 >= 3, "TestTime failed"); + CHECK(absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0)) + << "TestTime failed"; + CHECK_GE(cxt->g0, 3) << "TestTime failed"; start = absl::Now(); if (use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); } else { - ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), - "TestTime failed"); + CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1))) + << "TestTime failed"; } elapsed = absl::Now() - start; - ABSL_RAW_CHECK( - absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0), - "TestTime failed"); + CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0)) + << "TestTime failed"; if (use_cv) { cxt->cv.SignalAll(); } @@ -291,14 +288,13 @@ static void TestTime(TestContext *cxt, int c, bool use_cv) { if (use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1)); } else { - ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)), - "TestTime failed"); + CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1))) + << "TestTime failed"; } elapsed = absl::Now() - start; - ABSL_RAW_CHECK( - absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0), - "TestTime failed"); - ABSL_RAW_CHECK(cxt->g0 == cxt->threads, "TestTime failed"); + CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0)) + << "TestTime failed"; + CHECK_EQ(cxt->g0, cxt->threads) << "TestTime failed"; } else if (c == 1) { absl::MutexLock l(&cxt->mu); @@ -306,14 +302,12 @@ static void TestTime(TestContext *cxt, int c, bool use_cv) { if (use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500)); } else { - ABSL_RAW_CHECK( - !cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)), - "TestTime failed"); + CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500))) + << "TestTime failed"; } const absl::Duration elapsed = absl::Now() - start; - ABSL_RAW_CHECK( - absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9), - "TestTime failed"); + CHECK(absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9)) + << "TestTime failed"; cxt->g0++; } else if (c == 2) { absl::MutexLock l(&cxt->mu); @@ -322,8 +316,8 @@ static void TestTime(TestContext *cxt, int c, bool use_cv) { cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100)); } } else { - ABSL_RAW_CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)), - "TestTime failed"); + CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100))) + << "TestTime failed"; } cxt->g0++; } else { @@ -400,7 +394,7 @@ static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int), TestContext cxt; cxt.mu.EnableInvariantDebugging(invariant, &cxt); int ret = RunTestCommon(&cxt, test, threads, iterations, operations); - ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked"); + CHECK(GetInvariantChecked()) << "Invariant not checked"; absl::EnableMutexInvariantDebugging(false); // Restore. return ret; } @@ -1093,7 +1087,7 @@ static bool ConditionWithAcquire(AcquireFromConditionStruct *x) { absl::Milliseconds(100)); x->mu1.Unlock(); } - ABSL_RAW_CHECK(x->value < 4, "should not be invoked a fourth time"); + CHECK_LT(x->value, 4) << "should not be invoked a fourth time"; // We arrange for the condition to return true on only the 2nd and 3rd calls. return x->value == 2 || x->value == 3; @@ -1340,11 +1334,9 @@ static bool DelayIsWithinBounds(absl::Duration expected_delay, // different clock than absl::Now(), but these cases should be handled by the // the retry mechanism in each TimeoutTest. if (actual_delay < expected_delay) { - ABSL_RAW_LOG(WARNING, - "Actual delay %s was too short, expected %s (difference %s)", - absl::FormatDuration(actual_delay).c_str(), - absl::FormatDuration(expected_delay).c_str(), - absl::FormatDuration(actual_delay - expected_delay).c_str()); + LOG(WARNING) << "Actual delay " << actual_delay + << " was too short, expected " << expected_delay + << " (difference " << actual_delay - expected_delay << ")"; pass = false; } // If the expected delay is <= zero then allow a small error tolerance, since @@ -1355,11 +1347,9 @@ static bool DelayIsWithinBounds(absl::Duration expected_delay, ? absl::Milliseconds(10) : TimeoutTestAllowedSchedulingDelay(); if (actual_delay > expected_delay + tolerance) { - ABSL_RAW_LOG(WARNING, - "Actual delay %s was too long, expected %s (difference %s)", - absl::FormatDuration(actual_delay).c_str(), - absl::FormatDuration(expected_delay).c_str(), - absl::FormatDuration(actual_delay - expected_delay).c_str()); + LOG(WARNING) << "Actual delay " << actual_delay + << " was too long, expected " << expected_delay + << " (difference " << actual_delay - expected_delay << ")"; pass = false; } return pass; @@ -1409,12 +1399,6 @@ std::ostream &operator<<(std::ostream &os, const TimeoutTestParam ¶m) { << " expected_delay: " << param.expected_delay; } -std::string FormatString(const TimeoutTestParam ¶m) { - std::ostringstream os; - os << param; - return os.str(); -} - // Like `thread::Executor::ScheduleAt` except: // a) Delays zero or negative are executed immediately in the current thread. // b) Infinite delays are never scheduled. @@ -1544,13 +1528,13 @@ INSTANTIATE_TEST_SUITE_P(All, TimeoutTest, TEST_P(TimeoutTest, Await) { const TimeoutTestParam params = GetParam(); - ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); + LOG(INFO) << "Params: " << params; // Because this test asserts bounds on scheduling delays it is flaky. To // compensate it loops forever until it passes. Failures express as test // timeouts, in which case the test log can be used to diagnose the issue. for (int attempt = 1;; ++attempt) { - ABSL_RAW_LOG(INFO, "Attempt %d", attempt); + LOG(INFO) << "Attempt " << attempt; absl::Mutex mu; bool value = false; // condition value (under mu) @@ -1578,13 +1562,13 @@ TEST_P(TimeoutTest, Await) { TEST_P(TimeoutTest, LockWhen) { const TimeoutTestParam params = GetParam(); - ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); + LOG(INFO) << "Params: " << params; // Because this test asserts bounds on scheduling delays it is flaky. To // compensate it loops forever until it passes. Failures express as test // timeouts, in which case the test log can be used to diagnose the issue. for (int attempt = 1;; ++attempt) { - ABSL_RAW_LOG(INFO, "Attempt %d", attempt); + LOG(INFO) << "Attempt " << attempt; absl::Mutex mu; bool value = false; // condition value (under mu) @@ -1613,13 +1597,13 @@ TEST_P(TimeoutTest, LockWhen) { TEST_P(TimeoutTest, ReaderLockWhen) { const TimeoutTestParam params = GetParam(); - ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); + LOG(INFO) << "Params: " << params; // Because this test asserts bounds on scheduling delays it is flaky. To // compensate it loops forever until it passes. Failures express as test // timeouts, in which case the test log can be used to diagnose the issue. for (int attempt = 0;; ++attempt) { - ABSL_RAW_LOG(INFO, "Attempt %d", attempt); + LOG(INFO) << "Attempt " << attempt; absl::Mutex mu; bool value = false; // condition value (under mu) @@ -1649,13 +1633,13 @@ TEST_P(TimeoutTest, ReaderLockWhen) { TEST_P(TimeoutTest, Wait) { const TimeoutTestParam params = GetParam(); - ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str()); + LOG(INFO) << "Params: " << params; // Because this test asserts bounds on scheduling delays it is flaky. To // compensate it loops forever until it passes. Failures express as test // timeouts, in which case the test log can be used to diagnose the issue. for (int attempt = 0;; ++attempt) { - ABSL_RAW_LOG(INFO, "Attempt %d", attempt); + LOG(INFO) << "Attempt " << attempt; absl::Mutex mu; bool value = false; // condition value (under mu) diff --git a/absl/time/clock.cc b/absl/time/clock.cc index 2bf53d9c..aa74367b 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -48,17 +48,16 @@ Time Now() { ABSL_NAMESPACE_END } // namespace absl -// Decide if we should use the fast GetCurrentTimeNanos() algorithm -// based on the cyclecounter, otherwise just get the time directly -// from the OS on every call. This can be chosen at compile-time via +// Decide if we should use the fast GetCurrentTimeNanos() algorithm based on the +// cyclecounter, otherwise just get the time directly from the OS on every call. +// By default, the fast algorithm based on the cyclecount is disabled because in +// certain situations, for example, if the OS enters a "sleep" mode, it may +// produce incorrect values immediately upon waking. +// This can be chosen at compile-time via // -DABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS=[0|1] #ifndef ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS -#if ABSL_USE_UNSCALED_CYCLECLOCK -#define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 1 -#else #define ABSL_USE_CYCLECLOCK_FOR_GET_CURRENT_TIME_NANOS 0 #endif -#endif #if defined(__APPLE__) || defined(_WIN32) #include "absl/time/internal/get_current_time_chrono.inc" 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 f1f79a20..4a6c71f1 100644 --- a/absl/time/internal/cctz/src/time_zone_format_test.cc +++ b/absl/time/internal/cctz/src/time_zone_format_test.cc @@ -64,10 +64,13 @@ const char RFC1123_no_wday[] = "%d %b %Y %H:%M:%S %z"; template <typename D> void TestFormatSpecifier(time_point<D> tp, time_zone tz, const std::string& fmt, const std::string& ans) { - EXPECT_EQ(ans, format(fmt, tp, tz)) << fmt; - EXPECT_EQ("xxx " + ans, format("xxx " + fmt, tp, tz)); - EXPECT_EQ(ans + " yyy", format(fmt + " yyy", tp, tz)); - EXPECT_EQ("xxx " + ans + " yyy", format("xxx " + fmt + " yyy", tp, tz)); + EXPECT_EQ(ans, absl::time_internal::cctz::format(fmt, tp, tz)) << fmt; + EXPECT_EQ("xxx " + ans, + absl::time_internal::cctz::format("xxx " + fmt, tp, tz)); + EXPECT_EQ(ans + " yyy", + absl::time_internal::cctz::format(fmt + " yyy", tp, tz)); + EXPECT_EQ("xxx " + ans + " yyy", + absl::time_internal::cctz::format("xxx " + fmt + " yyy", tp, tz)); } } // namespace @@ -83,26 +86,29 @@ TEST(Format, TimePointResolution) { chrono::system_clock::from_time_t(1420167845) + chrono::milliseconds(123) + chrono::microseconds(456) + chrono::nanoseconds(789); - EXPECT_EQ( - "03:04:05.123456789", - format(kFmt, chrono::time_point_cast<chrono::nanoseconds>(t0), utc)); - EXPECT_EQ( - "03:04:05.123456", - format(kFmt, chrono::time_point_cast<chrono::microseconds>(t0), utc)); - EXPECT_EQ( - "03:04:05.123", - format(kFmt, chrono::time_point_cast<chrono::milliseconds>(t0), utc)); + EXPECT_EQ("03:04:05.123456789", + absl::time_internal::cctz::format( + kFmt, chrono::time_point_cast<chrono::nanoseconds>(t0), utc)); + EXPECT_EQ("03:04:05.123456", + absl::time_internal::cctz::format( + kFmt, chrono::time_point_cast<chrono::microseconds>(t0), utc)); + EXPECT_EQ("03:04:05.123", + absl::time_internal::cctz::format( + kFmt, chrono::time_point_cast<chrono::milliseconds>(t0), utc)); EXPECT_EQ("03:04:05", - format(kFmt, chrono::time_point_cast<chrono::seconds>(t0), utc)); + absl::time_internal::cctz::format( + kFmt, chrono::time_point_cast<chrono::seconds>(t0), utc)); EXPECT_EQ( "03:04:05", - format(kFmt, - chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0), - utc)); + absl::time_internal::cctz::format( + kFmt, chrono::time_point_cast<absl::time_internal::cctz::seconds>(t0), + utc)); EXPECT_EQ("03:04:00", - format(kFmt, chrono::time_point_cast<chrono::minutes>(t0), utc)); + absl::time_internal::cctz::format( + kFmt, chrono::time_point_cast<chrono::minutes>(t0), utc)); EXPECT_EQ("03:00:00", - format(kFmt, chrono::time_point_cast<chrono::hours>(t0), utc)); + absl::time_internal::cctz::format( + kFmt, chrono::time_point_cast<chrono::hours>(t0), utc)); } TEST(Format, TimePointExtendedResolution) { @@ -137,24 +143,28 @@ TEST(Format, Basics) { time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); // Starts with a couple basic edge cases. - EXPECT_EQ("", format("", tp, tz)); - EXPECT_EQ(" ", format(" ", tp, tz)); - EXPECT_EQ(" ", format(" ", tp, tz)); - EXPECT_EQ("xxx", format("xxx", tp, tz)); + EXPECT_EQ("", absl::time_internal::cctz::format("", tp, tz)); + EXPECT_EQ(" ", absl::time_internal::cctz::format(" ", tp, tz)); + EXPECT_EQ(" ", absl::time_internal::cctz::format(" ", tp, tz)); + EXPECT_EQ("xxx", absl::time_internal::cctz::format("xxx", tp, tz)); std::string big(128, 'x'); - EXPECT_EQ(big, format(big, tp, tz)); + EXPECT_EQ(big, absl::time_internal::cctz::format(big, tp, tz)); // Cause the 1024-byte buffer to grow. std::string bigger(100000, 'x'); - EXPECT_EQ(bigger, format(bigger, tp, tz)); + EXPECT_EQ(bigger, absl::time_internal::cctz::format(bigger, tp, tz)); tp += chrono::hours(13) + chrono::minutes(4) + chrono::seconds(5); tp += chrono::milliseconds(6) + chrono::microseconds(7) + chrono::nanoseconds(8); - EXPECT_EQ("1970-01-01", format("%Y-%m-%d", tp, tz)); - EXPECT_EQ("13:04:05", format("%H:%M:%S", tp, tz)); - EXPECT_EQ("13:04:05.006", format("%H:%M:%E3S", tp, tz)); - EXPECT_EQ("13:04:05.006007", format("%H:%M:%E6S", tp, tz)); - EXPECT_EQ("13:04:05.006007008", format("%H:%M:%E9S", tp, tz)); + EXPECT_EQ("1970-01-01", + absl::time_internal::cctz::format("%Y-%m-%d", tp, tz)); + EXPECT_EQ("13:04:05", absl::time_internal::cctz::format("%H:%M:%S", tp, tz)); + EXPECT_EQ("13:04:05.006", + absl::time_internal::cctz::format("%H:%M:%E3S", tp, tz)); + EXPECT_EQ("13:04:05.006007", + absl::time_internal::cctz::format("%H:%M:%E6S", tp, tz)); + EXPECT_EQ("13:04:05.006007008", + absl::time_internal::cctz::format("%H:%M:%E9S", tp, tz)); } TEST(Format, PosixConversions) { @@ -211,7 +221,8 @@ TEST(Format, LocaleSpecific) { TestFormatSpecifier(tp, tz, "%B", "January"); // %c should at least produce the numeric year and time-of-day. - const std::string s = format("%c", tp, utc_time_zone()); + const std::string s = + absl::time_internal::cctz::format("%c", tp, utc_time_zone()); EXPECT_THAT(s, testing::HasSubstr("1970")); EXPECT_THAT(s, testing::HasSubstr("00:00:00")); @@ -277,49 +288,61 @@ TEST(Format, ExtendedSeconds) { // No subseconds. time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); tp += chrono::seconds(5); - EXPECT_EQ("05", format("%E*S", tp, tz)); - EXPECT_EQ("05", format("%E0S", tp, tz)); - EXPECT_EQ("05.0", format("%E1S", tp, tz)); - EXPECT_EQ("05.00", format("%E2S", tp, tz)); - EXPECT_EQ("05.000", format("%E3S", tp, tz)); - EXPECT_EQ("05.0000", format("%E4S", tp, tz)); - EXPECT_EQ("05.00000", format("%E5S", tp, tz)); - EXPECT_EQ("05.000000", format("%E6S", tp, tz)); - EXPECT_EQ("05.0000000", format("%E7S", tp, tz)); - EXPECT_EQ("05.00000000", format("%E8S", tp, tz)); - EXPECT_EQ("05.000000000", format("%E9S", tp, tz)); - EXPECT_EQ("05.0000000000", format("%E10S", tp, tz)); - EXPECT_EQ("05.00000000000", format("%E11S", tp, tz)); - EXPECT_EQ("05.000000000000", format("%E12S", tp, tz)); - EXPECT_EQ("05.0000000000000", format("%E13S", tp, tz)); - EXPECT_EQ("05.00000000000000", format("%E14S", tp, tz)); - EXPECT_EQ("05.000000000000000", format("%E15S", tp, tz)); + EXPECT_EQ("05", absl::time_internal::cctz::format("%E*S", tp, tz)); + EXPECT_EQ("05", absl::time_internal::cctz::format("%E0S", tp, tz)); + EXPECT_EQ("05.0", absl::time_internal::cctz::format("%E1S", tp, tz)); + EXPECT_EQ("05.00", absl::time_internal::cctz::format("%E2S", tp, tz)); + EXPECT_EQ("05.000", absl::time_internal::cctz::format("%E3S", tp, tz)); + EXPECT_EQ("05.0000", absl::time_internal::cctz::format("%E4S", tp, tz)); + EXPECT_EQ("05.00000", absl::time_internal::cctz::format("%E5S", tp, tz)); + EXPECT_EQ("05.000000", absl::time_internal::cctz::format("%E6S", tp, tz)); + EXPECT_EQ("05.0000000", absl::time_internal::cctz::format("%E7S", tp, tz)); + EXPECT_EQ("05.00000000", absl::time_internal::cctz::format("%E8S", tp, tz)); + EXPECT_EQ("05.000000000", absl::time_internal::cctz::format("%E9S", tp, tz)); + EXPECT_EQ("05.0000000000", + absl::time_internal::cctz::format("%E10S", tp, tz)); + EXPECT_EQ("05.00000000000", + absl::time_internal::cctz::format("%E11S", tp, tz)); + EXPECT_EQ("05.000000000000", + absl::time_internal::cctz::format("%E12S", tp, tz)); + EXPECT_EQ("05.0000000000000", + absl::time_internal::cctz::format("%E13S", tp, tz)); + EXPECT_EQ("05.00000000000000", + absl::time_internal::cctz::format("%E14S", tp, tz)); + EXPECT_EQ("05.000000000000000", + absl::time_internal::cctz::format("%E15S", tp, tz)); // With subseconds. tp += chrono::milliseconds(6) + chrono::microseconds(7) + chrono::nanoseconds(8); - EXPECT_EQ("05.006007008", format("%E*S", tp, tz)); - EXPECT_EQ("05", format("%E0S", tp, tz)); - EXPECT_EQ("05.0", format("%E1S", tp, tz)); - EXPECT_EQ("05.00", format("%E2S", tp, tz)); - EXPECT_EQ("05.006", format("%E3S", tp, tz)); - EXPECT_EQ("05.0060", format("%E4S", tp, tz)); - EXPECT_EQ("05.00600", format("%E5S", tp, tz)); - EXPECT_EQ("05.006007", format("%E6S", tp, tz)); - EXPECT_EQ("05.0060070", format("%E7S", tp, tz)); - EXPECT_EQ("05.00600700", format("%E8S", tp, tz)); - EXPECT_EQ("05.006007008", format("%E9S", tp, tz)); - EXPECT_EQ("05.0060070080", format("%E10S", tp, tz)); - EXPECT_EQ("05.00600700800", format("%E11S", tp, tz)); - EXPECT_EQ("05.006007008000", format("%E12S", tp, tz)); - EXPECT_EQ("05.0060070080000", format("%E13S", tp, tz)); - EXPECT_EQ("05.00600700800000", format("%E14S", tp, tz)); - EXPECT_EQ("05.006007008000000", format("%E15S", tp, tz)); + EXPECT_EQ("05.006007008", absl::time_internal::cctz::format("%E*S", tp, tz)); + EXPECT_EQ("05", absl::time_internal::cctz::format("%E0S", tp, tz)); + EXPECT_EQ("05.0", absl::time_internal::cctz::format("%E1S", tp, tz)); + EXPECT_EQ("05.00", absl::time_internal::cctz::format("%E2S", tp, tz)); + EXPECT_EQ("05.006", absl::time_internal::cctz::format("%E3S", tp, tz)); + EXPECT_EQ("05.0060", absl::time_internal::cctz::format("%E4S", tp, tz)); + EXPECT_EQ("05.00600", absl::time_internal::cctz::format("%E5S", tp, tz)); + EXPECT_EQ("05.006007", absl::time_internal::cctz::format("%E6S", tp, tz)); + EXPECT_EQ("05.0060070", absl::time_internal::cctz::format("%E7S", tp, tz)); + EXPECT_EQ("05.00600700", absl::time_internal::cctz::format("%E8S", tp, tz)); + EXPECT_EQ("05.006007008", absl::time_internal::cctz::format("%E9S", tp, tz)); + EXPECT_EQ("05.0060070080", + absl::time_internal::cctz::format("%E10S", tp, tz)); + EXPECT_EQ("05.00600700800", + absl::time_internal::cctz::format("%E11S", tp, tz)); + EXPECT_EQ("05.006007008000", + absl::time_internal::cctz::format("%E12S", tp, tz)); + EXPECT_EQ("05.0060070080000", + absl::time_internal::cctz::format("%E13S", tp, tz)); + EXPECT_EQ("05.00600700800000", + absl::time_internal::cctz::format("%E14S", tp, tz)); + EXPECT_EQ("05.006007008000000", + absl::time_internal::cctz::format("%E15S", tp, tz)); // Times before the Unix epoch. tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1); EXPECT_EQ("1969-12-31 23:59:59.999999", - format("%Y-%m-%d %H:%M:%E*S", tp, tz)); + absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%E*S", tp, tz)); // Here is a "%E*S" case we got wrong for a while. While the first // instant below is correctly rendered as "...:07.333304", the second @@ -327,10 +350,10 @@ TEST(Format, ExtendedSeconds) { tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(1395024427333304); EXPECT_EQ("2014-03-17 02:47:07.333304", - format("%Y-%m-%d %H:%M:%E*S", tp, tz)); + absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%E*S", tp, tz)); tp += chrono::microseconds(1); EXPECT_EQ("2014-03-17 02:47:07.333305", - format("%Y-%m-%d %H:%M:%E*S", tp, tz)); + absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%E*S", tp, tz)); } TEST(Format, ExtendedSubeconds) { @@ -339,60 +362,69 @@ TEST(Format, ExtendedSubeconds) { // No subseconds. time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); tp += chrono::seconds(5); - EXPECT_EQ("0", format("%E*f", tp, tz)); - EXPECT_EQ("", format("%E0f", tp, tz)); - EXPECT_EQ("0", format("%E1f", tp, tz)); - EXPECT_EQ("00", format("%E2f", tp, tz)); - EXPECT_EQ("000", format("%E3f", tp, tz)); - EXPECT_EQ("0000", format("%E4f", tp, tz)); - EXPECT_EQ("00000", format("%E5f", tp, tz)); - EXPECT_EQ("000000", format("%E6f", tp, tz)); - EXPECT_EQ("0000000", format("%E7f", tp, tz)); - EXPECT_EQ("00000000", format("%E8f", tp, tz)); - EXPECT_EQ("000000000", format("%E9f", tp, tz)); - EXPECT_EQ("0000000000", format("%E10f", tp, tz)); - EXPECT_EQ("00000000000", format("%E11f", tp, tz)); - EXPECT_EQ("000000000000", format("%E12f", tp, tz)); - EXPECT_EQ("0000000000000", format("%E13f", tp, tz)); - EXPECT_EQ("00000000000000", format("%E14f", tp, tz)); - EXPECT_EQ("000000000000000", format("%E15f", tp, tz)); + EXPECT_EQ("0", absl::time_internal::cctz::format("%E*f", tp, tz)); + EXPECT_EQ("", absl::time_internal::cctz::format("%E0f", tp, tz)); + EXPECT_EQ("0", absl::time_internal::cctz::format("%E1f", tp, tz)); + EXPECT_EQ("00", absl::time_internal::cctz::format("%E2f", tp, tz)); + EXPECT_EQ("000", absl::time_internal::cctz::format("%E3f", tp, tz)); + EXPECT_EQ("0000", absl::time_internal::cctz::format("%E4f", tp, tz)); + EXPECT_EQ("00000", absl::time_internal::cctz::format("%E5f", tp, tz)); + EXPECT_EQ("000000", absl::time_internal::cctz::format("%E6f", tp, tz)); + EXPECT_EQ("0000000", absl::time_internal::cctz::format("%E7f", tp, tz)); + EXPECT_EQ("00000000", absl::time_internal::cctz::format("%E8f", tp, tz)); + EXPECT_EQ("000000000", absl::time_internal::cctz::format("%E9f", tp, tz)); + EXPECT_EQ("0000000000", absl::time_internal::cctz::format("%E10f", tp, tz)); + EXPECT_EQ("00000000000", absl::time_internal::cctz::format("%E11f", tp, tz)); + EXPECT_EQ("000000000000", absl::time_internal::cctz::format("%E12f", tp, tz)); + EXPECT_EQ("0000000000000", + absl::time_internal::cctz::format("%E13f", tp, tz)); + EXPECT_EQ("00000000000000", + absl::time_internal::cctz::format("%E14f", tp, tz)); + EXPECT_EQ("000000000000000", + absl::time_internal::cctz::format("%E15f", tp, tz)); // With subseconds. tp += chrono::milliseconds(6) + chrono::microseconds(7) + chrono::nanoseconds(8); - EXPECT_EQ("006007008", format("%E*f", tp, tz)); - EXPECT_EQ("", format("%E0f", tp, tz)); - EXPECT_EQ("0", format("%E1f", tp, tz)); - EXPECT_EQ("00", format("%E2f", tp, tz)); - EXPECT_EQ("006", format("%E3f", tp, tz)); - EXPECT_EQ("0060", format("%E4f", tp, tz)); - EXPECT_EQ("00600", format("%E5f", tp, tz)); - EXPECT_EQ("006007", format("%E6f", tp, tz)); - EXPECT_EQ("0060070", format("%E7f", tp, tz)); - EXPECT_EQ("00600700", format("%E8f", tp, tz)); - EXPECT_EQ("006007008", format("%E9f", tp, tz)); - EXPECT_EQ("0060070080", format("%E10f", tp, tz)); - EXPECT_EQ("00600700800", format("%E11f", tp, tz)); - EXPECT_EQ("006007008000", format("%E12f", tp, tz)); - EXPECT_EQ("0060070080000", format("%E13f", tp, tz)); - EXPECT_EQ("00600700800000", format("%E14f", tp, tz)); - EXPECT_EQ("006007008000000", format("%E15f", tp, tz)); + EXPECT_EQ("006007008", absl::time_internal::cctz::format("%E*f", tp, tz)); + EXPECT_EQ("", absl::time_internal::cctz::format("%E0f", tp, tz)); + EXPECT_EQ("0", absl::time_internal::cctz::format("%E1f", tp, tz)); + EXPECT_EQ("00", absl::time_internal::cctz::format("%E2f", tp, tz)); + EXPECT_EQ("006", absl::time_internal::cctz::format("%E3f", tp, tz)); + EXPECT_EQ("0060", absl::time_internal::cctz::format("%E4f", tp, tz)); + EXPECT_EQ("00600", absl::time_internal::cctz::format("%E5f", tp, tz)); + EXPECT_EQ("006007", absl::time_internal::cctz::format("%E6f", tp, tz)); + EXPECT_EQ("0060070", absl::time_internal::cctz::format("%E7f", tp, tz)); + EXPECT_EQ("00600700", absl::time_internal::cctz::format("%E8f", tp, tz)); + EXPECT_EQ("006007008", absl::time_internal::cctz::format("%E9f", tp, tz)); + EXPECT_EQ("0060070080", absl::time_internal::cctz::format("%E10f", tp, tz)); + EXPECT_EQ("00600700800", absl::time_internal::cctz::format("%E11f", tp, tz)); + EXPECT_EQ("006007008000", absl::time_internal::cctz::format("%E12f", tp, tz)); + EXPECT_EQ("0060070080000", + absl::time_internal::cctz::format("%E13f", tp, tz)); + EXPECT_EQ("00600700800000", + absl::time_internal::cctz::format("%E14f", tp, tz)); + EXPECT_EQ("006007008000000", + absl::time_internal::cctz::format("%E15f", tp, tz)); // Times before the Unix epoch. tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(-1); - EXPECT_EQ("1969-12-31 23:59:59.999999", - format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); + EXPECT_EQ( + "1969-12-31 23:59:59.999999", + absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); // Here is a "%E*S" case we got wrong for a while. While the first // instant below is correctly rendered as "...:07.333304", the second // one used to appear as "...:07.33330499999999999". tp = chrono::system_clock::from_time_t(0) + chrono::microseconds(1395024427333304); - EXPECT_EQ("2014-03-17 02:47:07.333304", - format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); + EXPECT_EQ( + "2014-03-17 02:47:07.333304", + absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); tp += chrono::microseconds(1); - EXPECT_EQ("2014-03-17 02:47:07.333305", - format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); + EXPECT_EQ( + "2014-03-17 02:47:07.333305", + absl::time_internal::cctz::format("%Y-%m-%d %H:%M:%S.%E*f", tp, tz)); } TEST(Format, CompareExtendSecondsVsSubseconds) { @@ -408,15 +440,17 @@ TEST(Format, CompareExtendSecondsVsSubseconds) { time_point<chrono::nanoseconds> tp = chrono::system_clock::from_time_t(0); tp += chrono::seconds(5); // ... %E*S and %S.%E*f are different. - EXPECT_EQ("05", format(fmt_A("*"), tp, tz)); - EXPECT_EQ("05.0", format(fmt_B("*"), tp, tz)); + EXPECT_EQ("05", absl::time_internal::cctz::format(fmt_A("*"), tp, tz)); + EXPECT_EQ("05.0", absl::time_internal::cctz::format(fmt_B("*"), tp, tz)); // ... %E0S and %S.%E0f are different. - EXPECT_EQ("05", format(fmt_A("0"), tp, tz)); - EXPECT_EQ("05.", format(fmt_B("0"), tp, tz)); + EXPECT_EQ("05", absl::time_internal::cctz::format(fmt_A("0"), tp, tz)); + EXPECT_EQ("05.", absl::time_internal::cctz::format(fmt_B("0"), tp, tz)); // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15]. for (int prec = 1; prec <= 15; ++prec) { - const std::string a = format(fmt_A(std::to_string(prec)), tp, tz); - const std::string b = format(fmt_B(std::to_string(prec)), tp, tz); + const std::string a = + absl::time_internal::cctz::format(fmt_A(std::to_string(prec)), tp, tz); + const std::string b = + absl::time_internal::cctz::format(fmt_B(std::to_string(prec)), tp, tz); EXPECT_EQ(a, b) << "prec=" << prec; } @@ -424,15 +458,19 @@ TEST(Format, CompareExtendSecondsVsSubseconds) { // ... %E*S and %S.%E*f are the same. tp += chrono::milliseconds(6) + chrono::microseconds(7) + chrono::nanoseconds(8); - EXPECT_EQ("05.006007008", format(fmt_A("*"), tp, tz)); - EXPECT_EQ("05.006007008", format(fmt_B("*"), tp, tz)); + EXPECT_EQ("05.006007008", + absl::time_internal::cctz::format(fmt_A("*"), tp, tz)); + EXPECT_EQ("05.006007008", + absl::time_internal::cctz::format(fmt_B("*"), tp, tz)); // ... %E0S and %S.%E0f are different. - EXPECT_EQ("05", format(fmt_A("0"), tp, tz)); - EXPECT_EQ("05.", format(fmt_B("0"), tp, tz)); + EXPECT_EQ("05", absl::time_internal::cctz::format(fmt_A("0"), tp, tz)); + EXPECT_EQ("05.", absl::time_internal::cctz::format(fmt_B("0"), tp, tz)); // ... %E<prec>S and %S.%E<prec>f are the same for prec in [1:15]. for (int prec = 1; prec <= 15; ++prec) { - const std::string a = format(fmt_A(std::to_string(prec)), tp, tz); - const std::string b = format(fmt_B(std::to_string(prec)), tp, tz); + const std::string a = + absl::time_internal::cctz::format(fmt_A(std::to_string(prec)), tp, tz); + const std::string b = + absl::time_internal::cctz::format(fmt_B(std::to_string(prec)), tp, tz); EXPECT_EQ(a, b) << "prec=" << prec; } } @@ -605,31 +643,31 @@ TEST(Format, ExtendedYears) { // %E4Y zero-pads the year to produce at least 4 chars, including the sign. auto tp = convert(civil_second(-999, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("-9991127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("-9991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(-99, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("-0991127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("-0991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(-9, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("-0091127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("-0091127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(-1, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("-0011127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("-0011127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(0, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("00001127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("00001127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(1, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("00011127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("00011127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(9, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("00091127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("00091127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(99, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("00991127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("00991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(999, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("09991127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("09991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(9999, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("99991127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("99991127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); // When the year is outside [-999:9999], more than 4 chars are produced. tp = convert(civil_second(-1000, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("-10001127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("-10001127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); tp = convert(civil_second(10000, 11, 27, 0, 0, 0), utc); - EXPECT_EQ("100001127", format(e4y_fmt, tp, utc)); + EXPECT_EQ("100001127", absl::time_internal::cctz::format(e4y_fmt, tp, utc)); } TEST(Format, RFC3339Format) { @@ -638,45 +676,64 @@ TEST(Format, RFC3339Format) { time_point<chrono::nanoseconds> tp = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::milliseconds(100); - EXPECT_EQ("1977-06-28T09:08:07.1-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.1-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::milliseconds(20); - EXPECT_EQ("1977-06-28T09:08:07.12-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.12-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::milliseconds(3); - EXPECT_EQ("1977-06-28T09:08:07.123-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.123-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::microseconds(400); - EXPECT_EQ("1977-06-28T09:08:07.1234-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.1234-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::microseconds(50); - EXPECT_EQ("1977-06-28T09:08:07.12345-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.12345-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::microseconds(6); - EXPECT_EQ("1977-06-28T09:08:07.123456-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.123456-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::nanoseconds(700); - EXPECT_EQ("1977-06-28T09:08:07.1234567-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.1234567-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::nanoseconds(80); - EXPECT_EQ("1977-06-28T09:08:07.12345678-07:00", format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07.12345678-07:00", + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); tp += chrono::nanoseconds(9); EXPECT_EQ("1977-06-28T09:08:07.123456789-07:00", - format(RFC3339_full, tp, tz)); - EXPECT_EQ("1977-06-28T09:08:07-07:00", format(RFC3339_sec, tp, tz)); + absl::time_internal::cctz::format(RFC3339_full, tp, tz)); + EXPECT_EQ("1977-06-28T09:08:07-07:00", + absl::time_internal::cctz::format(RFC3339_sec, tp, tz)); } TEST(Format, RFC1123Format) { // locale specific @@ -684,36 +741,50 @@ TEST(Format, RFC1123Format) { // locale specific EXPECT_TRUE(load_time_zone("America/Los_Angeles", &tz)); auto tp = convert(civil_second(1977, 6, 28, 9, 8, 7), tz); - EXPECT_EQ("Tue, 28 Jun 1977 09:08:07 -0700", format(RFC1123_full, tp, tz)); - EXPECT_EQ("28 Jun 1977 09:08:07 -0700", format(RFC1123_no_wday, tp, tz)); + EXPECT_EQ("Tue, 28 Jun 1977 09:08:07 -0700", + absl::time_internal::cctz::format(RFC1123_full, tp, tz)); + EXPECT_EQ("28 Jun 1977 09:08:07 -0700", + absl::time_internal::cctz::format(RFC1123_no_wday, tp, tz)); } TEST(Format, Week) { const time_zone utc = utc_time_zone(); auto tp = convert(civil_second(2017, 1, 1, 0, 0, 0), utc); - EXPECT_EQ("2017-01-7", format("%Y-%U-%u", tp, utc)); - EXPECT_EQ("2017-00-0", format("%Y-%W-%w", tp, utc)); + EXPECT_EQ("2017-01-7", + absl::time_internal::cctz::format("%Y-%U-%u", tp, utc)); + EXPECT_EQ("2017-00-0", + absl::time_internal::cctz::format("%Y-%W-%w", tp, utc)); tp = convert(civil_second(2017, 12, 31, 0, 0, 0), utc); - EXPECT_EQ("2017-53-7", format("%Y-%U-%u", tp, utc)); - EXPECT_EQ("2017-52-0", format("%Y-%W-%w", tp, utc)); + EXPECT_EQ("2017-53-7", + absl::time_internal::cctz::format("%Y-%U-%u", tp, utc)); + EXPECT_EQ("2017-52-0", + absl::time_internal::cctz::format("%Y-%W-%w", tp, utc)); tp = convert(civil_second(2018, 1, 1, 0, 0, 0), utc); - EXPECT_EQ("2018-00-1", format("%Y-%U-%u", tp, utc)); - EXPECT_EQ("2018-01-1", format("%Y-%W-%w", tp, utc)); + EXPECT_EQ("2018-00-1", + absl::time_internal::cctz::format("%Y-%U-%u", tp, utc)); + EXPECT_EQ("2018-01-1", + absl::time_internal::cctz::format("%Y-%W-%w", tp, utc)); tp = convert(civil_second(2018, 12, 31, 0, 0, 0), utc); - EXPECT_EQ("2018-52-1", format("%Y-%U-%u", tp, utc)); - EXPECT_EQ("2018-53-1", format("%Y-%W-%w", tp, utc)); + EXPECT_EQ("2018-52-1", + absl::time_internal::cctz::format("%Y-%U-%u", tp, utc)); + EXPECT_EQ("2018-53-1", + absl::time_internal::cctz::format("%Y-%W-%w", tp, utc)); tp = convert(civil_second(2019, 1, 1, 0, 0, 0), utc); - EXPECT_EQ("2019-00-2", format("%Y-%U-%u", tp, utc)); - EXPECT_EQ("2019-00-2", format("%Y-%W-%w", tp, utc)); + EXPECT_EQ("2019-00-2", + absl::time_internal::cctz::format("%Y-%U-%u", tp, utc)); + EXPECT_EQ("2019-00-2", + absl::time_internal::cctz::format("%Y-%W-%w", tp, utc)); tp = convert(civil_second(2019, 12, 31, 0, 0, 0), utc); - EXPECT_EQ("2019-52-2", format("%Y-%U-%u", tp, utc)); - EXPECT_EQ("2019-52-2", format("%Y-%W-%w", tp, utc)); + EXPECT_EQ("2019-52-2", + absl::time_internal::cctz::format("%Y-%U-%u", tp, utc)); + EXPECT_EQ("2019-52-2", + absl::time_internal::cctz::format("%Y-%W-%w", tp, utc)); } // @@ -726,39 +797,46 @@ TEST(Parse, TimePointResolution) { time_point<chrono::nanoseconds> tp_ns; EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_ns)); - EXPECT_EQ("03:04:05.123456789", format(kFmt, tp_ns, utc)); + EXPECT_EQ("03:04:05.123456789", + absl::time_internal::cctz::format(kFmt, tp_ns, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ns)); - EXPECT_EQ("03:04:05.123456", format(kFmt, tp_ns, utc)); + EXPECT_EQ("03:04:05.123456", + absl::time_internal::cctz::format(kFmt, tp_ns, utc)); time_point<chrono::microseconds> tp_us; EXPECT_TRUE(parse(kFmt, "03:04:05.123456789", utc, &tp_us)); - EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc)); + EXPECT_EQ("03:04:05.123456", + absl::time_internal::cctz::format(kFmt, tp_us, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_us)); - EXPECT_EQ("03:04:05.123456", format(kFmt, tp_us, utc)); + EXPECT_EQ("03:04:05.123456", + absl::time_internal::cctz::format(kFmt, tp_us, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_us)); - EXPECT_EQ("03:04:05.123", format(kFmt, tp_us, utc)); + EXPECT_EQ("03:04:05.123", + absl::time_internal::cctz::format(kFmt, tp_us, utc)); time_point<chrono::milliseconds> tp_ms; EXPECT_TRUE(parse(kFmt, "03:04:05.123456", utc, &tp_ms)); - EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc)); + EXPECT_EQ("03:04:05.123", + absl::time_internal::cctz::format(kFmt, tp_ms, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_ms)); - EXPECT_EQ("03:04:05.123", format(kFmt, tp_ms, utc)); + EXPECT_EQ("03:04:05.123", + absl::time_internal::cctz::format(kFmt, tp_ms, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_ms)); - EXPECT_EQ("03:04:05", format(kFmt, tp_ms, utc)); + EXPECT_EQ("03:04:05", absl::time_internal::cctz::format(kFmt, tp_ms, utc)); time_point<chrono::seconds> tp_s; EXPECT_TRUE(parse(kFmt, "03:04:05.123", utc, &tp_s)); - EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc)); + EXPECT_EQ("03:04:05", absl::time_internal::cctz::format(kFmt, tp_s, utc)); EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_s)); - EXPECT_EQ("03:04:05", format(kFmt, tp_s, utc)); + EXPECT_EQ("03:04:05", absl::time_internal::cctz::format(kFmt, tp_s, utc)); time_point<chrono::minutes> tp_m; EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_m)); - EXPECT_EQ("03:04:00", format(kFmt, tp_m, utc)); + EXPECT_EQ("03:04:00", absl::time_internal::cctz::format(kFmt, tp_m, utc)); time_point<chrono::hours> tp_h; EXPECT_TRUE(parse(kFmt, "03:04:05", utc, &tp_h)); - EXPECT_EQ("03:00:00", format(kFmt, tp_h, utc)); + EXPECT_EQ("03:00:00", absl::time_internal::cctz::format(kFmt, tp_h, utc)); } TEST(Parse, TimePointExtendedResolution) { @@ -1550,7 +1628,7 @@ TEST(Parse, TimePointOverflow) { parse(RFC3339_full, "2262-04-11T23:47:16.8547758079+00:00", utc, &tp)); EXPECT_EQ(tp, time_point<D>::max()); EXPECT_EQ("2262-04-11T23:47:16.854775807+00:00", - format(RFC3339_full, tp, utc)); + absl::time_internal::cctz::format(RFC3339_full, tp, utc)); #if 0 // TODO(#199): Will fail until cctz::parse() properly detects overflow. EXPECT_FALSE( @@ -1559,7 +1637,7 @@ TEST(Parse, TimePointOverflow) { parse(RFC3339_full, "1677-09-21T00:12:43.1452241920+00:00", utc, &tp)); EXPECT_EQ(tp, time_point<D>::min()); EXPECT_EQ("1677-09-21T00:12:43.145224192+00:00", - format(RFC3339_full, tp, utc)); + absl::time_internal::cctz::format(RFC3339_full, tp, utc)); EXPECT_FALSE( parse(RFC3339_full, "1677-09-21T00:12:43.1452241919+00:00", utc, &tp)); #endif @@ -1569,12 +1647,14 @@ TEST(Parse, TimePointOverflow) { EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T00:02:07.9+00:00", utc, &stp)); EXPECT_EQ(stp, time_point<DS>::max()); - EXPECT_EQ("1970-01-01T00:02:07+00:00", format(RFC3339_full, stp, utc)); + EXPECT_EQ("1970-01-01T00:02:07+00:00", + absl::time_internal::cctz::format(RFC3339_full, stp, utc)); EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T00:02:08+00:00", utc, &stp)); EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T23:57:52+00:00", utc, &stp)); EXPECT_EQ(stp, time_point<DS>::min()); - EXPECT_EQ("1969-12-31T23:57:52+00:00", format(RFC3339_full, stp, utc)); + EXPECT_EQ("1969-12-31T23:57:52+00:00", + absl::time_internal::cctz::format(RFC3339_full, stp, utc)); EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T23:57:51.9+00:00", utc, &stp)); using DM = chrono::duration<std::int8_t, chrono::minutes::period>; @@ -1582,12 +1662,14 @@ TEST(Parse, TimePointOverflow) { EXPECT_TRUE(parse(RFC3339_full, "1970-01-01T02:07:59+00:00", utc, &mtp)); EXPECT_EQ(mtp, time_point<DM>::max()); - EXPECT_EQ("1970-01-01T02:07:00+00:00", format(RFC3339_full, mtp, utc)); + EXPECT_EQ("1970-01-01T02:07:00+00:00", + absl::time_internal::cctz::format(RFC3339_full, mtp, utc)); EXPECT_FALSE(parse(RFC3339_full, "1970-01-01T02:08:00+00:00", utc, &mtp)); EXPECT_TRUE(parse(RFC3339_full, "1969-12-31T21:52:00+00:00", utc, &mtp)); EXPECT_EQ(mtp, time_point<DM>::min()); - EXPECT_EQ("1969-12-31T21:52:00+00:00", format(RFC3339_full, mtp, utc)); + EXPECT_EQ("1969-12-31T21:52:00+00:00", + absl::time_internal::cctz::format(RFC3339_full, mtp, utc)); EXPECT_FALSE(parse(RFC3339_full, "1969-12-31T21:51:59+00:00", utc, &mtp)); } @@ -1601,7 +1683,7 @@ TEST(Parse, TimePointOverflowFloor) { parse(RFC3339_full, "294247-01-10T04:00:54.7758079+00:00", utc, &tp)); EXPECT_EQ(tp, time_point<D>::max()); EXPECT_EQ("294247-01-10T04:00:54.775807+00:00", - format(RFC3339_full, tp, utc)); + absl::time_internal::cctz::format(RFC3339_full, tp, utc)); #if 0 // TODO(#199): Will fail until cctz::parse() properly detects overflow. EXPECT_FALSE( @@ -1610,7 +1692,7 @@ TEST(Parse, TimePointOverflowFloor) { parse(RFC3339_full, "-290308-12-21T19:59:05.2241920+00:00", utc, &tp)); EXPECT_EQ(tp, time_point<D>::min()); EXPECT_EQ("-290308-12-21T19:59:05.224192+00:00", - format(RFC3339_full, tp, utc)); + absl::time_internal::cctz::format(RFC3339_full, tp, utc)); EXPECT_FALSE( parse(RFC3339_full, "-290308-12-21T19:59:05.2241919+00:00", utc, &tp)); #endif @@ -1629,7 +1711,8 @@ TEST(FormatParse, RoundTrip) { // RFC3339, which renders subseconds. { time_point<chrono::nanoseconds> out; - const std::string s = format(RFC3339_full, in + subseconds, lax); + const std::string s = + absl::time_internal::cctz::format(RFC3339_full, in + subseconds, lax); EXPECT_TRUE(parse(RFC3339_full, s, lax, &out)) << s; EXPECT_EQ(in + subseconds, out); // RFC3339_full includes %Ez } @@ -1637,7 +1720,8 @@ TEST(FormatParse, RoundTrip) { // RFC1123, which only does whole seconds. { time_point<chrono::nanoseconds> out; - const std::string s = format(RFC1123_full, in, lax); + const std::string s = + absl::time_internal::cctz::format(RFC1123_full, in, lax); EXPECT_TRUE(parse(RFC1123_full, s, lax, &out)) << s; EXPECT_EQ(in, out); // RFC1123_full includes %z } @@ -1655,7 +1739,7 @@ TEST(FormatParse, RoundTrip) { { time_point<chrono::nanoseconds> out; time_zone utc = utc_time_zone(); - const std::string s = format("%c", in, utc); + const std::string s = absl::time_internal::cctz::format("%c", in, utc); EXPECT_TRUE(parse("%c", s, utc, &out)) << s; EXPECT_EQ(in, out); } @@ -1666,7 +1750,8 @@ TEST(FormatParse, RoundTripDistantFuture) { const time_zone utc = utc_time_zone(); const time_point<absl::time_internal::cctz::seconds> in = time_point<absl::time_internal::cctz::seconds>::max(); - const std::string s = format(RFC3339_full, in, utc); + const std::string s = + absl::time_internal::cctz::format(RFC3339_full, in, utc); time_point<absl::time_internal::cctz::seconds> out; EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s; EXPECT_EQ(in, out); @@ -1676,7 +1761,8 @@ TEST(FormatParse, RoundTripDistantPast) { const time_zone utc = utc_time_zone(); const time_point<absl::time_internal::cctz::seconds> in = time_point<absl::time_internal::cctz::seconds>::min(); - const std::string s = format(RFC3339_full, in, utc); + const std::string s = + absl::time_internal::cctz::format(RFC3339_full, in, utc); time_point<absl::time_internal::cctz::seconds> out; EXPECT_TRUE(parse(RFC3339_full, s, utc, &out)) << s; EXPECT_EQ(in, out); diff --git a/absl/time/internal/cctz/src/time_zone_lookup.cc b/absl/time/internal/cctz/src/time_zone_lookup.cc index f6983aeb..68084ce2 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup.cc @@ -35,6 +35,19 @@ #include <zircon/types.h> #endif +#if defined(_WIN32) +#include <sdkddkver.h> +// Include only when the SDK is for Windows 10 (and later), and the binary is +// targeted for Windows XP and later. +#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP) +#include <roapi.h> +#include <tchar.h> +#include <wchar.h> +#include <windows.globalization.h> +#include <windows.h> +#endif +#endif + #include <cstdlib> #include <cstring> #include <string> @@ -47,8 +60,8 @@ ABSL_NAMESPACE_BEGIN namespace time_internal { namespace cctz { -#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21 namespace { +#if defined(__ANDROID__) && defined(__ANDROID_API__) && __ANDROID_API__ >= 21 // Android 'L' removes __system_property_get() from the NDK, however // it is still a hidden symbol in libc so we use dlsym() to access it. // See Chromium's base/sys_info_android.cc for a similar example. @@ -72,9 +85,83 @@ int __system_property_get(const char* name, char* value) { static property_get_func system_property_get = LoadSystemPropertyGet(); return system_property_get ? system_property_get(name, value) : -1; } +#endif -} // namespace +#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP) +// Calls the WinRT Calendar.GetTimeZone method to obtain the IANA ID of the +// local time zone. Returns an empty vector in case of an error. +std::string win32_local_time_zone(const HMODULE combase) { + std::string result; + const auto ro_activate_instance = + reinterpret_cast<decltype(&RoActivateInstance)>( + GetProcAddress(combase, "RoActivateInstance")); + if (!ro_activate_instance) { + return result; + } + const auto windows_create_string_reference = + reinterpret_cast<decltype(&WindowsCreateStringReference)>( + GetProcAddress(combase, "WindowsCreateStringReference")); + if (!windows_create_string_reference) { + return result; + } + const auto windows_delete_string = + reinterpret_cast<decltype(&WindowsDeleteString)>( + GetProcAddress(combase, "WindowsDeleteString")); + if (!windows_delete_string) { + return result; + } + const auto windows_get_string_raw_buffer = + reinterpret_cast<decltype(&WindowsGetStringRawBuffer)>( + GetProcAddress(combase, "WindowsGetStringRawBuffer")); + if (!windows_get_string_raw_buffer) { + return result; + } + + // The string returned by WindowsCreateStringReference doesn't need to be + // deleted. + HSTRING calendar_class_id; + HSTRING_HEADER calendar_class_id_header; + HRESULT hr = windows_create_string_reference( + RuntimeClass_Windows_Globalization_Calendar, + sizeof(RuntimeClass_Windows_Globalization_Calendar) / sizeof(wchar_t) - 1, + &calendar_class_id_header, &calendar_class_id); + if (FAILED(hr)) { + return result; + } + + IInspectable* calendar; + hr = ro_activate_instance(calendar_class_id, &calendar); + if (FAILED(hr)) { + return result; + } + + ABI::Windows::Globalization::ITimeZoneOnCalendar* time_zone; + hr = calendar->QueryInterface(IID_PPV_ARGS(&time_zone)); + if (FAILED(hr)) { + calendar->Release(); + return result; + } + + HSTRING tz_hstr; + hr = time_zone->GetTimeZone(&tz_hstr); + if (SUCCEEDED(hr)) { + UINT32 wlen; + const PCWSTR tz_wstr = windows_get_string_raw_buffer(tz_hstr, &wlen); + if (tz_wstr) { + const int size = WideCharToMultiByte(CP_UTF8, 0, tz_wstr, wlen, nullptr, + 0, nullptr, nullptr); + result.resize(size); + WideCharToMultiByte(CP_UTF8, 0, tz_wstr, wlen, &result[0], size, nullptr, + nullptr); + } + windows_delete_string(tz_hstr); + } + time_zone->Release(); + calendar->Release(); + return result; +} #endif +} // namespace std::string time_zone::name() const { return effective_impl().Name(); } @@ -190,6 +277,39 @@ time_zone local_time_zone() { zone = primary_tz.c_str(); } #endif +#if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP) + // Use the WinRT Calendar class to get the local time zone. This feature is + // available on Windows 10 and later. The library is dynamically linked to + // maintain binary compatibility with Windows XP - Windows 7. On Windows 8, + // The combase.dll API functions are available but the RoActivateInstance + // call will fail for the Calendar class. + std::string winrt_tz; + const HMODULE combase = + LoadLibraryEx(_T("combase.dll"), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (combase) { + const auto ro_initialize = reinterpret_cast<decltype(&::RoInitialize)>( + GetProcAddress(combase, "RoInitialize")); + const auto ro_uninitialize = reinterpret_cast<decltype(&::RoUninitialize)>( + GetProcAddress(combase, "RoUninitialize")); + if (ro_initialize && ro_uninitialize) { + const HRESULT hr = ro_initialize(RO_INIT_MULTITHREADED); + // RPC_E_CHANGED_MODE means that a previous RoInitialize call specified + // a different concurrency model. The WinRT runtime is initialized and + // should work for our purpose here, but we should *not* call + // RoUninitialize because it's a failure. + if (SUCCEEDED(hr) || hr == RPC_E_CHANGED_MODE) { + winrt_tz = win32_local_time_zone(combase); + if (SUCCEEDED(hr)) { + ro_uninitialize(); + } + } + } + FreeLibrary(combase); + } + if (!winrt_tz.empty()) { + zone = winrt_tz.c_str(); + } +#endif // Allow ${TZ} to override to default zone. char* tz_env = nullptr; 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 ab461f04..4b093b37 100644 --- a/absl/time/internal/cctz/src/time_zone_lookup_test.cc +++ b/absl/time/internal/cctz/src/time_zone_lookup_test.cc @@ -911,19 +911,19 @@ TEST(MakeTime, TimePointResolution) { const time_zone utc = utc_time_zone(); const time_point<chrono::nanoseconds> tp_ns = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); - EXPECT_EQ("04:05", format("%M:%E*S", tp_ns, utc)); + EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_ns, utc)); const time_point<chrono::microseconds> tp_us = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); - EXPECT_EQ("04:05", format("%M:%E*S", tp_us, utc)); + EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_us, utc)); const time_point<chrono::milliseconds> tp_ms = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); - EXPECT_EQ("04:05", format("%M:%E*S", tp_ms, utc)); + EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_ms, utc)); const time_point<chrono::seconds> tp_s = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); - EXPECT_EQ("04:05", format("%M:%E*S", tp_s, utc)); + EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_s, utc)); const time_point<absl::time_internal::cctz::seconds> tp_s64 = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); - EXPECT_EQ("04:05", format("%M:%E*S", tp_s64, utc)); + EXPECT_EQ("04:05", absl::time_internal::cctz::format("%M:%E*S", tp_s64, utc)); // These next two require chrono::time_point_cast because the conversion // from a resolution of seconds (the return value of convert()) to a @@ -931,10 +931,10 @@ TEST(MakeTime, TimePointResolution) { const time_point<chrono::minutes> tp_m = chrono::time_point_cast<chrono::minutes>( convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); - EXPECT_EQ("04:00", format("%M:%E*S", tp_m, utc)); + EXPECT_EQ("04:00", absl::time_internal::cctz::format("%M:%E*S", tp_m, utc)); const time_point<chrono::hours> tp_h = chrono::time_point_cast<chrono::hours>( convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); - EXPECT_EQ("00:00", format("%M:%E*S", tp_h, utc)); + EXPECT_EQ("00:00", absl::time_internal::cctz::format("%M:%E*S", tp_h, utc)); } TEST(MakeTime, Normalization) { @@ -960,9 +960,11 @@ TEST(MakeTime, SysSecondsLimits) { // Approach the maximal time_point<cctz::seconds> value from below. tp = convert(civil_second(292277026596, 12, 4, 15, 30, 6), utc); - EXPECT_EQ("292277026596-12-04T15:30:06+00:00", format(RFC3339, tp, utc)); + EXPECT_EQ("292277026596-12-04T15:30:06+00:00", + absl::time_internal::cctz::format(RFC3339, tp, utc)); tp = convert(civil_second(292277026596, 12, 4, 15, 30, 7), utc); - EXPECT_EQ("292277026596-12-04T15:30:07+00:00", format(RFC3339, tp, utc)); + EXPECT_EQ("292277026596-12-04T15:30:07+00:00", + absl::time_internal::cctz::format(RFC3339, tp, utc)); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second(292277026596, 12, 4, 15, 30, 8), utc); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); @@ -971,7 +973,8 @@ TEST(MakeTime, SysSecondsLimits) { // Checks that we can also get the maximal value for a far-east zone. tp = convert(civil_second(292277026596, 12, 5, 5, 30, 7), east); - EXPECT_EQ("292277026596-12-05T05:30:07+14:00", format(RFC3339, tp, east)); + EXPECT_EQ("292277026596-12-05T05:30:07+14:00", + absl::time_internal::cctz::format(RFC3339, tp, east)); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second(292277026596, 12, 5, 5, 30, 8), east); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); @@ -980,7 +983,8 @@ TEST(MakeTime, SysSecondsLimits) { // Checks that we can also get the maximal value for a far-west zone. tp = convert(civil_second(292277026596, 12, 4, 1, 30, 7), west); - EXPECT_EQ("292277026596-12-04T01:30:07-14:00", format(RFC3339, tp, west)); + EXPECT_EQ("292277026596-12-04T01:30:07-14:00", + absl::time_internal::cctz::format(RFC3339, tp, west)); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); tp = convert(civil_second(292277026596, 12, 4, 7, 30, 8), west); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::max(), tp); @@ -989,9 +993,11 @@ TEST(MakeTime, SysSecondsLimits) { // Approach the minimal time_point<cctz::seconds> value from above. tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 53), utc); - EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", format(RFC3339, tp, utc)); + EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", + absl::time_internal::cctz::format(RFC3339, tp, utc)); tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 52), utc); - EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", format(RFC3339, tp, utc)); + EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", + absl::time_internal::cctz::format(RFC3339, tp, utc)); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 51), utc); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); @@ -1000,7 +1006,8 @@ TEST(MakeTime, SysSecondsLimits) { // Checks that we can also get the minimal value for a far-east zone. tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 52), east); - EXPECT_EQ("-292277022657-01-27T22:29:52+14:00", format(RFC3339, tp, east)); + EXPECT_EQ("-292277022657-01-27T22:29:52+14:00", + absl::time_internal::cctz::format(RFC3339, tp, east)); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second(-292277022657, 1, 27, 22, 29, 51), east); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); @@ -1009,7 +1016,8 @@ TEST(MakeTime, SysSecondsLimits) { // Checks that we can also get the minimal value for a far-west zone. tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 52), west); - EXPECT_EQ("-292277022657-01-26T18:29:52-14:00", format(RFC3339, tp, west)); + EXPECT_EQ("-292277022657-01-26T18:29:52-14:00", + absl::time_internal::cctz::format(RFC3339, tp, west)); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); tp = convert(civil_second(-292277022657, 1, 26, 18, 29, 51), west); EXPECT_EQ(time_point<absl::time_internal::cctz::seconds>::min(), tp); @@ -1029,14 +1037,16 @@ TEST(MakeTime, SysSecondsLimits) { #if defined(__FreeBSD__) || defined(__OpenBSD__) // The BSD gmtime_r() fails on extreme positive tm_year values. #else - EXPECT_EQ("2147485547-12-31T23:59:59+00:00", format(RFC3339, tp, cut)); + EXPECT_EQ("2147485547-12-31T23:59:59+00:00", + absl::time_internal::cctz::format(RFC3339, tp, cut)); #endif const year_t min_tm_year = year_t{std::numeric_limits<int>::min()} + 1900; tp = convert(civil_second(min_tm_year, 1, 1, 0, 0, 0), cut); #if defined(__Fuchsia__) // Fuchsia's gmtime_r() fails on extreme negative values (fxbug.dev/78527). #else - EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", format(RFC3339, tp, cut)); + EXPECT_EQ("-2147481748-01-01T00:00:00+00:00", + absl::time_internal::cctz::format(RFC3339, tp, cut)); #endif #endif } diff --git a/absl/time/time.cc b/absl/time/time.cc index a11e8e9b..d983c12b 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc @@ -66,6 +66,7 @@ inline int64_t FloorToUnit(absl::Duration d, absl::Duration unit) { : q - 1; } +ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING inline absl::Time::Breakdown InfiniteFutureBreakdown() { absl::Time::Breakdown bd; bd.year = std::numeric_limits<int64_t>::max(); @@ -99,6 +100,7 @@ inline absl::Time::Breakdown InfinitePastBreakdown() { bd.zone_abbr = "-00"; return bd; } +ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING inline absl::TimeZone::CivilInfo InfiniteFutureCivilInfo() { TimeZone::CivilInfo ci; @@ -120,6 +122,7 @@ inline absl::TimeZone::CivilInfo InfinitePastCivilInfo() { return ci; } +ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING inline absl::TimeConversion InfiniteFutureTimeConversion() { absl::TimeConversion tc; tc.pre = tc.trans = tc.post = absl::InfiniteFuture(); @@ -135,6 +138,7 @@ inline TimeConversion InfinitePastTimeConversion() { tc.normalized = true; return tc; } +ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING // Makes a Time from sec, overflowing to InfiniteFuture/InfinitePast as // necessary. If sec is min/max, then consult cs+tz to check for overflow. @@ -203,6 +207,7 @@ bool FindTransition(const cctz::time_zone& tz, // Time // +ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING absl::Time::Breakdown Time::In(absl::TimeZone tz) const { if (*this == absl::InfiniteFuture()) return InfiniteFutureBreakdown(); if (*this == absl::InfinitePast()) return InfinitePastBreakdown(); @@ -227,6 +232,7 @@ absl::Time::Breakdown Time::In(absl::TimeZone tz) const { bd.zone_abbr = al.abbr; return bd; } +ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING // // Conversions from/to other time types. @@ -398,7 +404,7 @@ bool TimeZone::PrevTransition(Time t, CivilTransition* trans) const { // // Conversions involving time zones. // - +ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, int min, int sec, TimeZone tz) { // Avoids years that are too extreme for CivilSecond to normalize. @@ -430,6 +436,7 @@ absl::TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, } return tc; } +ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING absl::Time FromTM(const struct tm& tm, absl::TimeZone tz) { civil_year_t tm_year = tm.tm_year; diff --git a/absl/time/time.h b/absl/time/time.h index 29178c77..37580805 100644 --- a/absl/time/time.h +++ b/absl/time/time.h @@ -802,8 +802,7 @@ class Time { // `absl::TimeZone`. // // Deprecated. Use `absl::TimeZone::CivilInfo`. - struct - Breakdown { + struct ABSL_DEPRECATED("Use `absl::TimeZone::CivilInfo`.") Breakdown { int64_t year; // year (e.g., 2013) int month; // month of year [1:12] int day; // day of month [1:31] @@ -829,7 +828,10 @@ class Time { // Returns the breakdown of this instant in the given TimeZone. // // Deprecated. Use `absl::TimeZone::At(Time)`. + ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING + ABSL_DEPRECATED("Use `absl::TimeZone::At(Time)`.") Breakdown In(TimeZone tz) const; + ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING template <typename H> friend H AbslHashValue(H h, Time t) { @@ -1323,8 +1325,7 @@ ABSL_ATTRIBUTE_PURE_FUNCTION inline Time FromCivil(CivilSecond ct, // `absl::ConvertDateTime()`. Legacy version of `absl::TimeZone::TimeInfo`. // // Deprecated. Use `absl::TimeZone::TimeInfo`. -struct - TimeConversion { +struct ABSL_DEPRECATED("Use `absl::TimeZone::TimeInfo`.") TimeConversion { Time pre; // time calculated using the pre-transition offset Time trans; // when the civil-time discontinuity occurred Time post; // time calculated using the post-transition offset @@ -1358,8 +1359,11 @@ struct // // absl::ToCivilDay(tc.pre, tz).day() == 1 // // Deprecated. Use `absl::TimeZone::At(CivilSecond)`. +ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING +ABSL_DEPRECATED("Use `absl::TimeZone::At(CivilSecond)`.") TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, int min, int sec, TimeZone tz); +ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING // FromDateTime() // @@ -1376,9 +1380,12 @@ TimeConversion ConvertDateTime(int64_t year, int mon, int day, int hour, // Deprecated. Use `absl::FromCivil(CivilSecond, TimeZone)`. Note that the // behavior of `FromCivil()` differs from `FromDateTime()` for skipped civil // times. If you care about that see `absl::TimeZone::At(absl::CivilSecond)`. -inline Time FromDateTime(int64_t year, int mon, int day, int hour, - int min, int sec, TimeZone tz) { +ABSL_DEPRECATED("Use `absl::FromCivil(CivilSecond, TimeZone)`.") +inline Time FromDateTime(int64_t year, int mon, int day, int hour, int min, + int sec, TimeZone tz) { + ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING return ConvertDateTime(year, mon, day, hour, min, sec, tz).pre; + ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING } // FromTM() diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel index bb801012..b57d3b9b 100644 --- a/absl/types/BUILD.bazel +++ b/absl/types/BUILD.bazel @@ -77,8 +77,8 @@ cc_test( ":any", "//absl/base:config", "//absl/base:exception_testing", - "//absl/base:raw_logging_internal", "//absl/container:test_instance_tracker", + "//absl/log", "@com_google_googletest//:gtest_main", ], ) @@ -185,7 +185,7 @@ cc_test( deps = [ ":optional", "//absl/base:config", - "//absl/base:raw_logging_internal", + "//absl/log", "//absl/meta:type_traits", "//absl/strings", "@com_google_googletest//:gtest_main", diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt index 830953ae..c0dcee79 100644 --- a/absl/types/CMakeLists.txt +++ b/absl/types/CMakeLists.txt @@ -68,7 +68,7 @@ absl_cc_test( absl::any absl::config absl::exception_testing - absl::raw_logging_internal + absl::log absl::test_instance_tracker GTest::gmock_main ) @@ -220,7 +220,7 @@ absl_cc_test( DEPS absl::optional absl::config - absl::raw_logging_internal + absl::log absl::strings absl::type_traits GTest::gmock_main diff --git a/absl/types/any_test.cc b/absl/types/any_test.cc index d382b927..666ea5b6 100644 --- a/absl/types/any_test.cc +++ b/absl/types/any_test.cc @@ -25,8 +25,8 @@ #include "gtest/gtest.h" #include "absl/base/config.h" #include "absl/base/internal/exception_testing.h" -#include "absl/base/internal/raw_logging.h" #include "absl/container/internal/test_instance_tracker.h" +#include "absl/log/log.h" namespace { using absl::test_internal::CopyableOnlyInstance; @@ -704,7 +704,7 @@ struct BadCopyable { #ifdef ABSL_HAVE_EXCEPTIONS throw BadCopy(); #else - ABSL_RAW_LOG(FATAL, "Bad copy"); + LOG(FATAL) << "Bad copy"; #endif } }; diff --git a/absl/types/optional_test.cc b/absl/types/optional_test.cc index bd5fe082..5da297b0 100644 --- a/absl/types/optional_test.cc +++ b/absl/types/optional_test.cc @@ -23,7 +23,7 @@ #include "gtest/gtest.h" #include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" +#include "absl/log/log.h" #include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" @@ -1542,8 +1542,7 @@ TEST(optionalTest, Hash) { struct MoveMeNoThrow { MoveMeNoThrow() : x(0) {} [[noreturn]] MoveMeNoThrow(const MoveMeNoThrow& other) : x(other.x) { - ABSL_RAW_LOG(FATAL, "Should not be called."); - abort(); + LOG(FATAL) << "Should not be called."; } MoveMeNoThrow(MoveMeNoThrow&& other) noexcept : x(other.x) {} int x; diff --git a/ci/linux_docker_containers.sh b/ci/linux_docker_containers.sh index dcaf18b9..4dfa3175 100644 --- a/ci/linux_docker_containers.sh +++ b/ci/linux_docker_containers.sh @@ -17,5 +17,5 @@ readonly LINUX_ALPINE_CONTAINER="gcr.io/google.com/absl-177019/alpine:20201026" readonly LINUX_CLANG_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20230217" -readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20230217" +readonly LINUX_GCC_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20230517" readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20230120" |