diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake index ac23f25..4944823 100644 --- a/CMake/AbseilDll.cmake +++ b/CMake/AbseilDll.cmake
@@ -374,6 +374,7 @@ "strings/internal/str_split_internal.h" "strings/internal/utf8.cc" "strings/internal/utf8.h" + "strings/resize_and_overwrite.h" "synchronization/barrier.cc" "synchronization/barrier.h" "synchronization/blocking_counter.cc"
diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h index 21f00ae..f4f41d0 100644 --- a/absl/container/internal/btree_container.h +++ b/absl/container/internal/btree_container.h
@@ -640,12 +640,12 @@ } template <class K = key_type, int = EnableIf<LifetimeBoundK<K, false>>()> mapped_type &operator[](key_arg<K> &&k) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return try_emplace(std::forward<K>(k)).first->second; + return try_emplace(std::forward<key_arg<K>>(k)).first->second; } template <class K = key_type, int &..., EnableIf<LifetimeBoundK<K, true>> = 0> mapped_type &operator[](key_arg<K> &&k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY( this)) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return this->template operator[]<K, 0>(std::forward<K>(k)); + return this->template operator[]<K, 0>(std::forward<key_arg<K>>(k)); } template <typename K = key_type>
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index b42a4f2..85adf87 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h
@@ -205,7 +205,8 @@ !std::is_convertible<K, const_iterator>::value, int>::type = 0> std::pair<iterator, bool> try_emplace(key_arg<K> &&k, Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return try_emplace_impl(std::forward<K>(k), std::forward<Args>(args)...); + return try_emplace_impl(std::forward<key_arg<K>>(k), + std::forward<Args>(args)...); } template <class K = key_type, class... Args, @@ -215,7 +216,7 @@ std::pair<iterator, bool> try_emplace( key_arg<K> &&k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this), Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return this->template try_emplace<K, 0>(std::forward<K>(k), + return this->template try_emplace<K, 0>(std::forward<key_arg<K>>(k), std::forward<Args>(args)...); } @@ -241,14 +242,15 @@ class... Args> iterator try_emplace(const_iterator, key_arg<K> &&k, Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return try_emplace(std::forward<K>(k), std::forward<Args>(args)...).first; + return try_emplace(std::forward<key_arg<K>>(k), std::forward<Args>(args)...) + .first; } template <class K = key_type, class... Args, EnableIf<LifetimeBoundK<K, true, K *>> = 0> iterator try_emplace(const_iterator hint, key_arg<K> &&k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this), Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return this->template try_emplace<K, 0>(hint, std::forward<K>(k), + return this->template try_emplace<K, 0>(hint, std::forward<key_arg<K>>(k), std::forward<Args>(args)...); } @@ -264,7 +266,7 @@ const key_arg<K> &k ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this), Args &&...args) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return this->template try_emplace<K, 0>(hint, std::forward<K>(k), + return this->template try_emplace<K, 0>(hint, k, std::forward<Args>(args)...); } @@ -296,15 +298,15 @@ // It is safe to use unchecked_deref here because try_emplace // will always return an iterator pointing to a valid item in the table, // since it inserts if nothing is found for the given key. - return Policy::value( - &this->unchecked_deref(try_emplace(std::forward<K>(key)).first)); + return Policy::value(&this->unchecked_deref( + try_emplace(std::forward<key_arg<K>>(key)).first)); } template <class K = key_type, class P = Policy, int &..., EnableIf<LifetimeBoundK<K, true, K *>> = 0> MappedReference<P> operator[]( key_arg<K> &&key ABSL_INTERNAL_ATTRIBUTE_CAPTURED_BY(this)) ABSL_ATTRIBUTE_LIFETIME_BOUND { - return this->template operator[]<K, P, 0>(std::forward<K>(key)); + return this->template operator[]<K, P, 0>(std::forward<key_arg<K>>(key)); } template <class K = key_type, class P = Policy,
diff --git a/absl/flags/BUILD.bazel b/absl/flags/BUILD.bazel index 532721d..f928609 100644 --- a/absl/flags/BUILD.bazel +++ b/absl/flags/BUILD.bazel
@@ -168,6 +168,7 @@ linkopts = ABSL_DEFAULT_LINKOPTS, visibility = [ "//absl/flags:__pkg__", + "//absl/flags/rust:__pkg__", ], deps = [ ":commandlineflag",
diff --git a/absl/flags/declare.h b/absl/flags/declare.h index 8d2a856..a0b12bb 100644 --- a/absl/flags/declare.h +++ b/absl/flags/declare.h
@@ -59,10 +59,19 @@ // Internal implementation of ABSL_DECLARE_FLAG to allow macro expansion of its // arguments. Clients must use ABSL_DECLARE_FLAG instead. +// +// The non-MSVC implementation declares the flag twice. This is to allow +// applying attributes to the second declaration. However, this causes a +// compile error (C4273) in MSVC if a `__declspec` is prepended to the macro. +#if defined(_MSC_VER) +#define ABSL_DECLARE_FLAG_INTERNAL(type, name) \ + extern absl::Flag<type> FLAGS_##name +#else #define ABSL_DECLARE_FLAG_INTERNAL(type, name) \ extern absl::Flag<type> FLAGS_##name; \ namespace absl /* block flags in namespaces */ {} \ /* second redeclaration is to allow applying attributes */ \ extern absl::Flag<type> FLAGS_##name +#endif // _MSC_VER #endif // ABSL_FLAGS_DECLARE_H_
diff --git a/absl/functional/any_invocable.h b/absl/functional/any_invocable.h index ade6cff..6dd72b6 100644 --- a/absl/functional/any_invocable.h +++ b/absl/functional/any_invocable.h
@@ -39,6 +39,7 @@ #include <type_traits> #include <utility> +#include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/nullability.h" #include "absl/functional/internal/any_invocable.h" @@ -159,7 +160,7 @@ // AnyInvocable<void()> empty; // empty(); // WARNING: Undefined behavior! template <class Sig> -class ABSL_NULLABILITY_COMPATIBLE AnyInvocable +class ABSL_NULLABILITY_COMPATIBLE ABSL_ATTRIBUTE_OWNER AnyInvocable : private internal_any_invocable::Impl<Sig> { private: static_assert( @@ -171,6 +172,7 @@ public: // The return type of Sig using result_type = typename Impl::result_type; + using absl_internal_is_view = std::false_type; // Constructors
diff --git a/absl/functional/function_ref.h b/absl/functional/function_ref.h index fe52853..3882eb0 100644 --- a/absl/functional/function_ref.h +++ b/absl/functional/function_ref.h
@@ -85,7 +85,7 @@ // bool Visitor(absl::FunctionRef<void(my_proto&, absl::string_view)> // callback); template <typename R, typename... Args> -class FunctionRef<R(Args...)> { +class ABSL_ATTRIBUTE_VIEW FunctionRef<R(Args...)> { protected: // Used to disable constructors for objects that are not compatible with the // signature of this FunctionRef. @@ -158,6 +158,8 @@ } #endif + using absl_internal_is_view = std::true_type; + // Call the underlying object. R operator()(Args... args) const { return invoker_(ptr_, std::forward<Args>(args)...); @@ -171,7 +173,8 @@ // Allow const qualified function signatures. Since FunctionRef requires // constness anyway we can just make this a no-op. template <typename R, typename... Args> -class FunctionRef<R(Args...) const> : private FunctionRef<R(Args...)> { +class ABSL_ATTRIBUTE_VIEW + FunctionRef<R(Args...) const> : private FunctionRef<R(Args...)> { using Base = FunctionRef<R(Args...)>; template <typename F, typename... U> @@ -215,6 +218,8 @@ : Base(arg, obj) {} #endif + using absl_internal_is_view = std::true_type; + using Base::operator(); };
diff --git a/absl/functional/function_ref_test.cc b/absl/functional/function_ref_test.cc index a0c6745..97aa3d5 100644 --- a/absl/functional/function_ref_test.cc +++ b/absl/functional/function_ref_test.cc
@@ -407,7 +407,7 @@ // producing a copy rather than another indirection. absl::FunctionRef<int()> a = +[]() { return 1; }; absl::FunctionRef<int() const> b = a; - a = []() { return 2; }; + a = +[]() { return 2; }; EXPECT_EQ(b(), 2); }
diff --git a/absl/log/log.h b/absl/log/log.h index f1cab9d..371c32f 100644 --- a/absl/log/log.h +++ b/absl/log/log.h
@@ -247,11 +247,11 @@ // However, simply testing whether verbose logging is enabled can be expensive. // If you don't intend to enable verbose logging in non-debug builds, consider // using `DVLOG` instead. -#define VLOG(severity) ABSL_LOG_INTERNAL_VLOG_IMPL(severity) +#define VLOG(verbose_level) ABSL_LOG_INTERNAL_VLOG_IMPL(verbose_level) // `DVLOG` behaves like `VLOG` in debug mode (i.e. `#ifndef NDEBUG`). // Otherwise, it compiles away and does nothing. -#define DVLOG(severity) ABSL_LOG_INTERNAL_DVLOG_IMPL(severity) +#define DVLOG(verbose_level) ABSL_LOG_INTERNAL_DVLOG_IMPL(verbose_level) // `LOG_IF` and friends add a second argument which specifies a condition. If // the condition is false, nothing is logged.
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index 2e73f80..bcf0c38 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel
@@ -142,6 +142,31 @@ ], ) +cc_library( + name = "resize_and_overwrite", + hdrs = ["resize_and_overwrite.h"], + copts = ABSL_DEFAULT_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + "//absl/base:config", + "//absl/base:core_headers", + "//absl/base:throw_delegate", + ], +) + +cc_test( + name = "resize_and_overwrite_test", + srcs = ["resize_and_overwrite_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = ABSL_DEFAULT_LINKOPTS, + deps = [ + ":resize_and_overwrite", + "//absl/log:absl_check", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) + cc_test( name = "match_test", size = "small", @@ -1095,12 +1120,12 @@ name = "resize_uninitialized_test", size = "small", srcs = [ - "internal/resize_uninitialized.h", "internal/resize_uninitialized_test.cc", ], copts = ABSL_TEST_COPTS, visibility = ["//visibility:private"], deps = [ + ":internal", "//absl/base:core_headers", "//absl/meta:type_traits", "@googletest//:gtest",
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt index 32ad263..764d5cd 100644 --- a/absl/strings/CMakeLists.txt +++ b/absl/strings/CMakeLists.txt
@@ -141,6 +141,32 @@ absl::type_traits ) +absl_cc_library( + NAME + strings_resize_and_overwrite + HDRS + "resize_and_overwrite.h" + COPTS + ${ABSL_DEFAULT_COPTS} + DEPS + absl::config + absl::core_headers + absl::throw_delegate +) + +absl_cc_test( + NAME + strings_resize_and_overwrite_test + SRCS + "resize_and_overwrite_test.cc" + COPTS + ${ABSL_TEST_COPTS} + DEPS + absl::strings_resize_and_overwrite + absl::absl_check + GTest::gmock_main +) + absl_cc_test( NAME match_test @@ -337,11 +363,11 @@ NAME resize_uninitialized_test SRCS - "internal/resize_uninitialized.h" "internal/resize_uninitialized_test.cc" COPTS ${ABSL_TEST_COPTS} DEPS + absl::strings_internal absl::base absl::core_headers absl::type_traits
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index 5045811..6637561 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h
@@ -381,6 +381,8 @@ this->releaser_invoker = &Release; } + const Releaser* releaser() const { return &this->template get<0>(); } + ~CordRepExternalImpl() { InvokeReleaser(Rank1{}, std::move(this->template get<0>()), absl::string_view(base, length));
diff --git a/absl/strings/resize_and_overwrite.h b/absl/strings/resize_and_overwrite.h new file mode 100644 index 0000000..7d07640 --- /dev/null +++ b/absl/strings/resize_and_overwrite.h
@@ -0,0 +1,172 @@ +// Copyright 2025 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: resize_and_overwrite.h +// ----------------------------------------------------------------------------- +// +// This file contains a polyfill for C++23's +// std::basic_string<CharT,Traits,Allocator>::resize_and_overwrite +// +// The polyfill takes the form of a free function: + +// template<typename T, typename Op> +// void StringResizeAndOverwrite(T& str, typename T::size_type count, Op op); +// +// This avoids the cost of initializing a suitably-sized std::string when it is +// intended to be used as a char array, for example, to be populated by a +// C-style API. +// +// Example usage: +// +// std::string IntToString(int n) { +// std::string result; +// constexpr size_t kMaxIntChars = 10; +// absl::StringResizeAndOverwrite( +// result, kMaxIntChars, [n](char* buffer, size_t buffer_size) { +// return snprintf(buffer, buffer_size, "%d", n); +// }); +// return result; +// } +// +// https://en.cppreference.com/w/cpp/string/basic_string/resize_and_overwrite.html +// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1072r10.html + +#ifndef ABSL_STRINGS_RESIZE_AND_OVERWRITE_H_ +#define ABSL_STRINGS_RESIZE_AND_OVERWRITE_H_ + +#include <cstddef> +#include <string> // IWYU pragma: keep +#include <type_traits> +#include <utility> + +#include "absl/base/config.h" +#include "absl/base/internal/throw_delegate.h" +#include "absl/base/macros.h" +#include "absl/base/optimization.h" + +#if defined(__cpp_lib_string_resize_and_overwrite) && \ + __cpp_lib_string_resize_and_overwrite >= 202110L +#define ABSL_INTERNAL_HAS_RESIZE_AND_OVERWRITE 1 +#endif + +namespace absl { +ABSL_NAMESPACE_BEGIN + +namespace strings_internal { + +#ifndef ABSL_INTERNAL_HAS_RESIZE_AND_OVERWRITE + +inline size_t ProbeResizeAndOverwriteOp(char*, size_t) { return 0; } + +// Prior to C++23, Google's libc++ backports resize_and_overwrite as +// __google_nonstandard_backport_resize_and_overwrite +template <typename T, typename = void> +struct has__google_nonstandard_backport_resize_and_overwrite : std::false_type { +}; + +template <typename T> +struct has__google_nonstandard_backport_resize_and_overwrite< + T, + std::void_t< + decltype(std::declval<T&>() + .__google_nonstandard_backport_resize_and_overwrite( + std::declval<size_t>(), ProbeResizeAndOverwriteOp))>> + : std::true_type {}; + +// Prior to C++23, the version of libstdc++ that shipped with GCC >= 14 +// has __resize_and_overwrite. +template <typename T, typename = void> +struct has__resize_and_overwrite : std::false_type {}; + +template <typename T> +struct has__resize_and_overwrite< + T, std::void_t<decltype(std::declval<T&>().__resize_and_overwrite( + std::declval<size_t>(), ProbeResizeAndOverwriteOp))>> + : std::true_type {}; + +// libc++ used __resize_default_init to achieve uninitialized string resizes +// before removing it September 2025, in favor of resize_and_overwrite. +// https://github.com/llvm/llvm-project/commit/92f5d8df361bb1bb6dea88f86faeedfd295ab970 +template <typename T, typename = void> +struct has__resize_default_init : std::false_type {}; + +template <typename T> +struct has__resize_default_init< + T, std::void_t<decltype(std::declval<T&>().__resize_default_init(42))>> + : std::true_type {}; + +// Prior to C++23, some versions of MSVC have _Resize_and_overwrite. +template <typename T, typename = void> +struct has_Resize_and_overwrite : std::false_type {}; + +template <typename T> +struct has_Resize_and_overwrite< + T, std::void_t<decltype(std::declval<T&>()._Resize_and_overwrite( + std::declval<size_t>(), ProbeResizeAndOverwriteOp))>> + : std::true_type {}; + +#endif // ifndef ABSL_INTERNAL_HAS_RESIZE_AND_OVERWRITE + +// A less-efficient fallback implementation that uses resize(). +template <typename T, typename Op> +void StringResizeAndOverwriteFallback(T& str, typename T::size_type n, Op op) { + if (ABSL_PREDICT_FALSE(n > str.max_size())) { + absl::base_internal::ThrowStdLengthError("absl::StringResizeAndOverwrite"); + } + // The callback is allowed to write an arbitrary value to buf+n, but it is + // undefined behavior to write anything other than T::value_type{} to + // str.data()[n]. Therefore the initial resize uses an extra byte. + str.resize(n + 1); + auto new_size = std::move(op)(str.data(), n); + ABSL_HARDENING_ASSERT(new_size >= 0 && new_size <= n); + str.erase(static_cast<typename T::size_type>(new_size)); +} + +} // namespace strings_internal + +// Resizes `str` to contain at most `n` characters, using the user-provided +// operation `op` to modify the possibly indeterminate contents. `op` must +// return the finalized length of `str`. Note that `op` is allowed write to +// `data()[n]`, which facilitiates interoperation with functions that write a +// trailing NUL. +template <typename T, typename Op> +void StringResizeAndOverwrite(T& str, typename T::size_type n, Op op) { +#ifdef ABSL_INTERNAL_HAS_RESIZE_AND_OVERWRITE + str.resize_and_overwrite(n, std::move(op)); +#else + if constexpr (strings_internal:: + has__google_nonstandard_backport_resize_and_overwrite< + T>::value) { + str.__google_nonstandard_backport_resize_and_overwrite(n, std::move(op)); + } else if constexpr (strings_internal::has__resize_and_overwrite<T>::value) { + str.__resize_and_overwrite(n, std::move(op)); + } else if constexpr (strings_internal::has__resize_default_init<T>::value) { + str.__resize_default_init(n); + str.__resize_default_init( + static_cast<typename T::size_type>(std::move(op)(str.data(), n))); + } else if constexpr (strings_internal::has_Resize_and_overwrite<T>::value) { + str._Resize_and_overwrite(n, std::move(op)); + } else { + strings_internal::StringResizeAndOverwriteFallback(str, n, op); + } +#endif +} + +ABSL_NAMESPACE_END +} // namespace absl + +#undef ABSL_INTERNAL_HAS_RESIZE_AND_OVERWRITE + +#endif // ABSL_STRINGS_RESIZE_AND_OVERWRITE_H_
diff --git a/absl/strings/resize_and_overwrite_test.cc b/absl/strings/resize_and_overwrite_test.cc new file mode 100644 index 0000000..ad4cca9 --- /dev/null +++ b/absl/strings/resize_and_overwrite_test.cc
@@ -0,0 +1,119 @@ +// Copyright 2025 The Abseil Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/strings/resize_and_overwrite.h" + +#include <algorithm> +#include <cstddef> +#include <string> + +#include "gtest/gtest.h" +#include "absl/log/absl_check.h" + +namespace { + +struct ResizeAndOverwriteParam { + size_t initial_size; + size_t requested_capacity; + size_t final_size; +}; + +using StringResizeAndOverwriteTest = + ::testing::TestWithParam<ResizeAndOverwriteParam>; + +TEST_P(StringResizeAndOverwriteTest, StringResizeAndOverwrite) { + const auto& param = GetParam(); + std::string s(param.initial_size, 'a'); + absl::StringResizeAndOverwrite( + s, param.requested_capacity, [&](char* p, size_t n) { + ABSL_CHECK_EQ(n, param.requested_capacity); + if (param.final_size >= param.initial_size) { + // Append case. + std::fill(p + param.initial_size, p + param.final_size, 'b'); + } else if (param.final_size > 0) { + // Truncate case. + p[param.final_size - 1] = 'b'; + } + p[param.final_size] = 'c'; // Should be overwritten with '\0'; + return param.final_size; + }); + + std::string expected; + if (param.final_size >= param.initial_size) { + // Append case. + expected = std::string(param.initial_size, 'a') + + std::string(param.final_size - param.initial_size, 'b'); + } else if (param.final_size > 0) { + // Truncate case. + expected = std::string(param.final_size - 1, 'a') + std::string("b"); + } + + EXPECT_EQ(s, expected); + EXPECT_EQ(s.c_str()[param.final_size], '\0'); +} + +TEST_P(StringResizeAndOverwriteTest, StringResizeAndOverwriteFallback) { + const auto& param = GetParam(); + std::string s(param.initial_size, 'a'); + absl::strings_internal::StringResizeAndOverwriteFallback( + s, param.requested_capacity, [&](char* p, size_t n) { + ABSL_CHECK_EQ(n, param.requested_capacity); + if (param.final_size >= param.initial_size) { + // Append case. + std::fill(p + param.initial_size, p + param.final_size, 'b'); + } else if (param.final_size > 0) { + // Truncate case. + p[param.final_size - 1] = 'b'; + } + p[param.final_size] = 'c'; // Should be overwritten with '\0'; + return param.final_size; + }); + + std::string expected; + if (param.final_size >= param.initial_size) { + // Append case. + expected = std::string(param.initial_size, 'a') + + std::string(param.final_size - param.initial_size, 'b'); + } else if (param.final_size > 0) { + // Truncate case. + expected = std::string(param.final_size - 1, 'a') + std::string("b"); + } + + EXPECT_EQ(s, expected); + EXPECT_EQ(s.c_str()[param.final_size], '\0'); +} + +// clang-format off +INSTANTIATE_TEST_SUITE_P(StringResizeAndOverwriteTestSuite, + StringResizeAndOverwriteTest, + ::testing::ValuesIn<ResizeAndOverwriteParam>({ + // Append cases. + {0, 10, 5}, + {10, 10, 10}, + {10, 15, 15}, + {10, 20, 15}, + {10, 40, 40}, + {10, 50, 40}, + {30, 35, 35}, + {30, 45, 35}, + {10, 30, 15}, + // Truncate cases. + {15, 15, 10}, + {40, 40, 35}, + {40, 30, 10}, + {10, 15, 0}, + })); +// clang-format on + +} // namespace
diff --git a/absl/time/civil_time_benchmark.cc b/absl/time/civil_time_benchmark.cc index 2de0233..2818a90 100644 --- a/absl/time/civil_time_benchmark.cc +++ b/absl/time/civil_time_benchmark.cc
@@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "absl/time/civil_time.h" - #include <cstddef> #include <numeric> #include <string> #include <vector> #include "absl/hash/hash.h" +#include "absl/time/civil_time.h" #include "benchmark/benchmark.h" namespace {
diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc index 6e5c35d..a0cb29c 100644 --- a/absl/time/civil_time_test.cc +++ b/absl/time/civil_time_test.cc
@@ -78,8 +78,7 @@ absl::FormatCivilTime(absl::CivilMinute(2015, 1, 2))); EXPECT_EQ("2015-01-01T00:00", absl::FormatCivilTime(absl::CivilMinute(2015, 1))); - EXPECT_EQ("2015-01-01T00:00", - absl::FormatCivilTime(absl::CivilMinute(2015))); + EXPECT_EQ("2015-01-01T00:00", absl::FormatCivilTime(absl::CivilMinute(2015))); EXPECT_EQ("2015-01-02T03", absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3, 4, 5))); @@ -89,82 +88,63 @@ absl::FormatCivilTime(absl::CivilHour(2015, 1, 2, 3))); EXPECT_EQ("2015-01-02T00", absl::FormatCivilTime(absl::CivilHour(2015, 1, 2))); - EXPECT_EQ("2015-01-01T00", - absl::FormatCivilTime(absl::CivilHour(2015, 1))); - EXPECT_EQ("2015-01-01T00", - absl::FormatCivilTime(absl::CivilHour(2015))); + EXPECT_EQ("2015-01-01T00", absl::FormatCivilTime(absl::CivilHour(2015, 1))); + EXPECT_EQ("2015-01-01T00", absl::FormatCivilTime(absl::CivilHour(2015))); EXPECT_EQ("2015-01-02", absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4, 5))); EXPECT_EQ("2015-01-02", absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3, 4))); - EXPECT_EQ("2015-01-02", - absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3))); - EXPECT_EQ("2015-01-02", - absl::FormatCivilTime(absl::CivilDay(2015, 1, 2))); - EXPECT_EQ("2015-01-01", - absl::FormatCivilTime(absl::CivilDay(2015, 1))); - EXPECT_EQ("2015-01-01", - absl::FormatCivilTime(absl::CivilDay(2015))); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(absl::CivilDay(2015, 1, 2, 3))); + EXPECT_EQ("2015-01-02", absl::FormatCivilTime(absl::CivilDay(2015, 1, 2))); + EXPECT_EQ("2015-01-01", absl::FormatCivilTime(absl::CivilDay(2015, 1))); + EXPECT_EQ("2015-01-01", absl::FormatCivilTime(absl::CivilDay(2015))); EXPECT_EQ("2015-01", absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4, 5))); EXPECT_EQ("2015-01", absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3, 4))); - EXPECT_EQ("2015-01", - absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3))); - EXPECT_EQ("2015-01", - absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2))); - EXPECT_EQ("2015-01", - absl::FormatCivilTime(absl::CivilMonth(2015, 1))); - EXPECT_EQ("2015-01", - absl::FormatCivilTime(absl::CivilMonth(2015))); + EXPECT_EQ("2015-01", absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2, 3))); + EXPECT_EQ("2015-01", absl::FormatCivilTime(absl::CivilMonth(2015, 1, 2))); + EXPECT_EQ("2015-01", absl::FormatCivilTime(absl::CivilMonth(2015, 1))); + EXPECT_EQ("2015-01", absl::FormatCivilTime(absl::CivilMonth(2015))); EXPECT_EQ("2015", absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4, 5))); - EXPECT_EQ("2015", - absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4))); - EXPECT_EQ("2015", - absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3))); - EXPECT_EQ("2015", - absl::FormatCivilTime(absl::CivilYear(2015, 1, 2))); - EXPECT_EQ("2015", - absl::FormatCivilTime(absl::CivilYear(2015, 1))); - EXPECT_EQ("2015", - absl::FormatCivilTime(absl::CivilYear(2015))); + EXPECT_EQ("2015", absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3, 4))); + EXPECT_EQ("2015", absl::FormatCivilTime(absl::CivilYear(2015, 1, 2, 3))); + EXPECT_EQ("2015", absl::FormatCivilTime(absl::CivilYear(2015, 1, 2))); + EXPECT_EQ("2015", absl::FormatCivilTime(absl::CivilYear(2015, 1))); + EXPECT_EQ("2015", absl::FormatCivilTime(absl::CivilYear(2015))); } TEST(CivilTime, FieldsConstructionLimits) { const int kIntMax = std::numeric_limits<int>::max(); - EXPECT_EQ("2038-01-19T03:14:07", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, 1, 0, 0, kIntMax))); - EXPECT_EQ("6121-02-11T05:21:07", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, 1, 0, kIntMax, kIntMax))); + EXPECT_EQ("2038-01-19T03:14:07", absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, 0, kIntMax))); + EXPECT_EQ("6121-02-11T05:21:07", absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, kIntMax, kIntMax))); EXPECT_EQ("251104-11-20T12:21:07", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, 1, kIntMax, kIntMax, kIntMax))); + absl::FormatCivilTime( + absl::CivilSecond(1970, 1, 1, kIntMax, kIntMax, kIntMax))); EXPECT_EQ("6130715-05-30T12:21:07", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, kIntMax, kIntMax, kIntMax, kIntMax))); + absl::FormatCivilTime(absl::CivilSecond(1970, 1, kIntMax, kIntMax, + kIntMax, kIntMax))); EXPECT_EQ("185087685-11-26T12:21:07", absl::FormatCivilTime(absl::CivilSecond( 1970, kIntMax, kIntMax, kIntMax, kIntMax, kIntMax))); const int kIntMin = std::numeric_limits<int>::min(); - EXPECT_EQ("1901-12-13T20:45:52", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, 1, 0, 0, kIntMin))); - EXPECT_EQ("-2182-11-20T18:37:52", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, 1, 0, kIntMin, kIntMin))); + EXPECT_EQ("1901-12-13T20:45:52", absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, 0, kIntMin))); + EXPECT_EQ("-2182-11-20T18:37:52", absl::FormatCivilTime(absl::CivilSecond( + 1970, 1, 1, 0, kIntMin, kIntMin))); EXPECT_EQ("-247165-02-11T10:37:52", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, 1, kIntMin, kIntMin, kIntMin))); + absl::FormatCivilTime( + absl::CivilSecond(1970, 1, 1, kIntMin, kIntMin, kIntMin))); EXPECT_EQ("-6126776-08-01T10:37:52", - absl::FormatCivilTime(absl::CivilSecond( - 1970, 1, kIntMin, kIntMin, kIntMin, kIntMin))); + absl::FormatCivilTime(absl::CivilSecond(1970, 1, kIntMin, kIntMin, + kIntMin, kIntMin))); EXPECT_EQ("-185083747-10-31T10:37:52", absl::FormatCivilTime(absl::CivilSecond( 1970, kIntMin, kIntMin, kIntMin, kIntMin, kIntMin))); @@ -173,14 +153,10 @@ TEST(CivilTime, RangeLimits) { const absl::civil_year_t kYearMax = std::numeric_limits<absl::civil_year_t>::max(); - EXPECT_EQ(absl::CivilYear(kYearMax), - absl::CivilYear::max()); - EXPECT_EQ(absl::CivilMonth(kYearMax, 12), - absl::CivilMonth::max()); - EXPECT_EQ(absl::CivilDay(kYearMax, 12, 31), - absl::CivilDay::max()); - EXPECT_EQ(absl::CivilHour(kYearMax, 12, 31, 23), - absl::CivilHour::max()); + EXPECT_EQ(absl::CivilYear(kYearMax), absl::CivilYear::max()); + EXPECT_EQ(absl::CivilMonth(kYearMax, 12), absl::CivilMonth::max()); + EXPECT_EQ(absl::CivilDay(kYearMax, 12, 31), absl::CivilDay::max()); + EXPECT_EQ(absl::CivilHour(kYearMax, 12, 31, 23), absl::CivilHour::max()); EXPECT_EQ(absl::CivilMinute(kYearMax, 12, 31, 23, 59), absl::CivilMinute::max()); EXPECT_EQ(absl::CivilSecond(kYearMax, 12, 31, 23, 59, 59), @@ -188,16 +164,11 @@ const absl::civil_year_t kYearMin = std::numeric_limits<absl::civil_year_t>::min(); - EXPECT_EQ(absl::CivilYear(kYearMin), - absl::CivilYear::min()); - EXPECT_EQ(absl::CivilMonth(kYearMin, 1), - absl::CivilMonth::min()); - EXPECT_EQ(absl::CivilDay(kYearMin, 1, 1), - absl::CivilDay::min()); - EXPECT_EQ(absl::CivilHour(kYearMin, 1, 1, 0), - absl::CivilHour::min()); - EXPECT_EQ(absl::CivilMinute(kYearMin, 1, 1, 0, 0), - absl::CivilMinute::min()); + EXPECT_EQ(absl::CivilYear(kYearMin), absl::CivilYear::min()); + EXPECT_EQ(absl::CivilMonth(kYearMin, 1), absl::CivilMonth::min()); + EXPECT_EQ(absl::CivilDay(kYearMin, 1, 1), absl::CivilDay::min()); + EXPECT_EQ(absl::CivilHour(kYearMin, 1, 1, 0), absl::CivilHour::min()); + EXPECT_EQ(absl::CivilMinute(kYearMin, 1, 1, 0, 0), absl::CivilMinute::min()); EXPECT_EQ(absl::CivilSecond(kYearMin, 1, 1, 0, 0, 0), absl::CivilSecond::min()); } @@ -250,8 +221,7 @@ (std::is_convertible<absl::CivilSecond, absl::CivilMinute>::value)); EXPECT_FALSE( (std::is_convertible<absl::CivilSecond, absl::CivilHour>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilSecond, absl::CivilDay>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilSecond, absl::CivilDay>::value)); EXPECT_FALSE( (std::is_convertible<absl::CivilSecond, absl::CivilMonth>::value)); EXPECT_FALSE( @@ -259,27 +229,20 @@ EXPECT_FALSE( (std::is_convertible<absl::CivilMinute, absl::CivilHour>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilMinute, absl::CivilDay>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilMinute, absl::CivilDay>::value)); EXPECT_FALSE( (std::is_convertible<absl::CivilMinute, absl::CivilMonth>::value)); EXPECT_FALSE( (std::is_convertible<absl::CivilMinute, absl::CivilYear>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilHour, absl::CivilDay>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilHour, absl::CivilMonth>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilHour, absl::CivilYear>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilHour, absl::CivilDay>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilHour, absl::CivilMonth>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilHour, absl::CivilYear>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilDay, absl::CivilMonth>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilDay, absl::CivilYear>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilDay, absl::CivilMonth>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilDay, absl::CivilYear>::value)); - EXPECT_FALSE( - (std::is_convertible<absl::CivilMonth, absl::CivilYear>::value)); + EXPECT_FALSE((std::is_convertible<absl::CivilMonth, absl::CivilYear>::value)); } TEST(CivilTime, ExplicitCrossAlignment) { @@ -417,8 +380,7 @@ // Tests the relational operators of two different civil-time types. TEST_RELATIONAL(absl::CivilDay(2014, 1, 1), absl::CivilMinute(2014, 1, 1, 1, 1)); - TEST_RELATIONAL(absl::CivilDay(2014, 1, 1), - absl::CivilMonth(2014, 2)); + TEST_RELATIONAL(absl::CivilDay(2014, 1, 1), absl::CivilMonth(2014, 2)); #undef TEST_RELATIONAL } @@ -812,8 +774,7 @@ EXPECT_EQ("-9223372036854775808-01-01T00:00", absl::FormatCivilTime(mm)); absl::CivilHour hh; - EXPECT_TRUE( - absl::ParseLenientCivilTime("9223372036854775807-12-31T23", &hh)); + EXPECT_TRUE(absl::ParseLenientCivilTime("9223372036854775807-12-31T23", &hh)); EXPECT_EQ("9223372036854775807-12-31T23", absl::FormatCivilTime(hh)); EXPECT_TRUE( absl::ParseLenientCivilTime("-9223372036854775808-01-01T00", &hh)); @@ -1181,19 +1142,13 @@ int day; } leap_day; // The date of the day after Feb 28. } kLeapYearTable[]{ - {1900, 365, {3, 1}}, - {1999, 365, {3, 1}}, + {1900, 365, {3, 1}}, {1999, 365, {3, 1}}, {2000, 366, {2, 29}}, // leap year - {2001, 365, {3, 1}}, - {2002, 365, {3, 1}}, - {2003, 365, {3, 1}}, - {2004, 366, {2, 29}}, // leap year - {2005, 365, {3, 1}}, - {2006, 365, {3, 1}}, - {2007, 365, {3, 1}}, - {2008, 366, {2, 29}}, // leap year - {2009, 365, {3, 1}}, - {2100, 365, {3, 1}}, + {2001, 365, {3, 1}}, {2002, 365, {3, 1}}, + {2003, 365, {3, 1}}, {2004, 366, {2, 29}}, // leap year + {2005, 365, {3, 1}}, {2006, 365, {3, 1}}, + {2007, 365, {3, 1}}, {2008, 366, {2, 29}}, // leap year + {2009, 365, {3, 1}}, {2100, 365, {3, 1}}, }; for (int i = 0; i < ABSL_ARRAYSIZE(kLeapYearTable); ++i) { @@ -1223,7 +1178,7 @@ // Bonus: Date of Thanksgiving in the United States // Rule: Fourth Thursday of November - const absl::CivilDay thanksgiving = thursday + 7 * 3; + const absl::CivilDay thanksgiving = thursday + 7 * 3; EXPECT_EQ("2014-11-27", absl::FormatCivilTime(thanksgiving)); }
diff --git a/absl/time/clock.cc b/absl/time/clock.cc index bdcd85b..bf6a10b 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc
@@ -125,7 +125,7 @@ // spin-delay tuning. // Acquire seqlock (*seq) and return the value to be written to unlock. -static inline uint64_t SeqAcquire(std::atomic<uint64_t> *seq) { +static inline uint64_t SeqAcquire(std::atomic<uint64_t>* seq) { uint64_t x = seq->fetch_add(1, std::memory_order_relaxed); // We put a release fence between update to *seq and writes to shared data. @@ -140,7 +140,7 @@ // Release seqlock (*seq) by writing x to it---a value previously returned by // SeqAcquire. -static inline void SeqRelease(std::atomic<uint64_t> *seq, uint64_t x) { +static inline void SeqRelease(std::atomic<uint64_t>* seq, uint64_t x) { // The unlock store to *seq must have release ordering so that all // updates to shared data must finish before this store. seq->store(x, std::memory_order_release); // release lock for readers @@ -218,7 +218,7 @@ // assumed to be complete resyncs, which shouldn't happen. If they do, a full // reinitialization of the outer algorithm should occur.) static int64_t GetCurrentTimeNanosFromKernel(uint64_t last_cycleclock, - uint64_t *cycleclock) + uint64_t* cycleclock) ABSL_EXCLUSIVE_LOCKS_REQUIRED(time_state.lock) { uint64_t local_approx_syscall_time_in_cycles = // local copy time_state.approx_syscall_time_in_cycles.load(std::memory_order_relaxed); @@ -274,8 +274,8 @@ // Read the contents of *atomic into *sample. // Each field is read atomically, but to maintain atomicity between fields, // the access must be done under a lock. -static void ReadTimeSampleAtomic(const struct TimeSampleAtomic *atomic, - struct TimeSample *sample) { +static void ReadTimeSampleAtomic(const struct TimeSampleAtomic* atomic, + struct TimeSample* sample) { sample->base_ns = atomic->base_ns.load(std::memory_order_relaxed); sample->base_cycles = atomic->base_cycles.load(std::memory_order_relaxed); sample->nsscaled_per_cycle = @@ -397,7 +397,7 @@ static uint64_t UpdateLastSample( uint64_t now_cycles, uint64_t now_ns, uint64_t delta_cycles, - const struct TimeSample *sample) ABSL_ATTRIBUTE_COLD; + const struct TimeSample* sample) ABSL_ATTRIBUTE_COLD; // The slow path of GetCurrentTimeNanos(). This is taken while gathering // initial samples, when enough time has elapsed since the last sample, and if @@ -454,7 +454,7 @@ // for readers. Returns the new estimated time. static uint64_t UpdateLastSample(uint64_t now_cycles, uint64_t now_ns, uint64_t delta_cycles, - const struct TimeSample *sample) + const struct TimeSample* sample) ABSL_EXCLUSIVE_LOCKS_REQUIRED(time_state.lock) { uint64_t estimated_base_ns = now_ns; uint64_t lock_value =
diff --git a/absl/time/clock_test.cc b/absl/time/clock_test.cc index bc77dbc..fb1452a 100644 --- a/absl/time/clock_test.cc +++ b/absl/time/clock_test.cc
@@ -114,8 +114,8 @@ EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, AlarmPolicy::kWithoutAlarm)); #if defined(ABSL_HAVE_ALARM) - EXPECT_TRUE(AssertSleepForBounded(d, early, late, timeout, - AlarmPolicy::kWithAlarm)); + EXPECT_TRUE( + AssertSleepForBounded(d, early, late, timeout, AlarmPolicy::kWithAlarm)); #endif }
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index 164ad6b..dc14665 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc
@@ -57,8 +57,7 @@ // timespec ts1, ts2; // EXPECT_THAT(ts1, TimespecMatcher(ts2)); MATCHER_P(TimespecMatcher, ts, "") { - if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec) - return true; + if (ts.tv_sec == arg.tv_sec && ts.tv_nsec == arg.tv_nsec) return true; *result_listener << "expected: {" << ts.tv_sec << ", " << ts.tv_nsec << "} "; *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_nsec << "}"; return false; @@ -68,8 +67,7 @@ // timeval tv1, tv2; // EXPECT_THAT(tv1, TimevalMatcher(tv2)); MATCHER_P(TimevalMatcher, tv, "") { - if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec) - return true; + if (tv.tv_sec == arg.tv_sec && tv.tv_usec == arg.tv_usec) return true; *result_listener << "expected: {" << tv.tv_sec << ", " << tv.tv_usec << "} "; *result_listener << "actual: {" << arg.tv_sec << ", " << arg.tv_usec << "}"; return false; @@ -223,12 +221,12 @@ template <int64_t N> void TestFromChronoBasicEquality() { - using std::chrono::nanoseconds; + using std::chrono::hours; using std::chrono::microseconds; using std::chrono::milliseconds; - using std::chrono::seconds; using std::chrono::minutes; - using std::chrono::hours; + using std::chrono::nanoseconds; + using std::chrono::seconds; static_assert(absl::Nanoseconds(N) == absl::FromChrono(nanoseconds(N)), ""); static_assert(absl::Microseconds(N) == absl::FromChrono(microseconds(N)), ""); @@ -288,12 +286,12 @@ template <int64_t N> void TestToChrono() { - using std::chrono::nanoseconds; + using std::chrono::hours; using std::chrono::microseconds; using std::chrono::milliseconds; - using std::chrono::seconds; using std::chrono::minutes; - using std::chrono::hours; + using std::chrono::nanoseconds; + using std::chrono::seconds; EXPECT_EQ(nanoseconds(N), absl::ToChronoNanoseconds(absl::Nanoseconds(N))); EXPECT_EQ(microseconds(N), absl::ToChronoMicroseconds(absl::Microseconds(N))); @@ -320,12 +318,12 @@ } TEST(Duration, ToChrono) { - using std::chrono::nanoseconds; + using std::chrono::hours; using std::chrono::microseconds; using std::chrono::milliseconds; - using std::chrono::seconds; using std::chrono::minutes; - using std::chrono::hours; + using std::chrono::nanoseconds; + using std::chrono::seconds; TestToChrono<kint64min>(); TestToChrono<-1>(); @@ -546,18 +544,18 @@ const absl::Duration sec_min = absl::Seconds(kint64min); const absl::Duration inf = absl::InfiniteDuration(); -#define TEST_INF_MUL_WITH_TYPE(T) \ - EXPECT_EQ(inf, inf * static_cast<T>(2)); \ - EXPECT_EQ(-inf, inf * static_cast<T>(-2)); \ - EXPECT_EQ(-inf, -inf * static_cast<T>(2)); \ - EXPECT_EQ(inf, -inf * static_cast<T>(-2)); \ - EXPECT_EQ(inf, inf * static_cast<T>(0)); \ - EXPECT_EQ(-inf, -inf * static_cast<T>(0)); \ - EXPECT_EQ(inf, sec_max * static_cast<T>(2)); \ - EXPECT_EQ(inf, sec_min * static_cast<T>(-2)); \ - EXPECT_EQ(inf, (sec_max / static_cast<T>(2)) * static_cast<T>(3)); \ - EXPECT_EQ(-inf, sec_max * static_cast<T>(-2)); \ - EXPECT_EQ(-inf, sec_min * static_cast<T>(2)); \ +#define TEST_INF_MUL_WITH_TYPE(T) \ + EXPECT_EQ(inf, inf* static_cast<T>(2)); \ + EXPECT_EQ(-inf, inf* static_cast<T>(-2)); \ + EXPECT_EQ(-inf, -inf* static_cast<T>(2)); \ + EXPECT_EQ(inf, -inf* static_cast<T>(-2)); \ + EXPECT_EQ(inf, inf* static_cast<T>(0)); \ + EXPECT_EQ(-inf, -inf* static_cast<T>(0)); \ + EXPECT_EQ(inf, sec_max* static_cast<T>(2)); \ + EXPECT_EQ(inf, sec_min* static_cast<T>(-2)); \ + EXPECT_EQ(inf, (sec_max / static_cast<T>(2)) * static_cast<T>(3)); \ + EXPECT_EQ(-inf, sec_max* static_cast<T>(-2)); \ + EXPECT_EQ(-inf, sec_min* static_cast<T>(2)); \ EXPECT_EQ(-inf, (sec_min / static_cast<T>(2)) * static_cast<T>(3)); TEST_INF_MUL_WITH_TYPE(int64_t); // NOLINT(readability/function) @@ -932,9 +930,9 @@ #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON TEST(Duration, SpaceshipOperators) { -#define TEST_REL_OPS(UNIT) \ +#define TEST_REL_OPS(UNIT) \ static_assert(UNIT(2) <=> UNIT(2) == std::strong_ordering::equal, ""); \ - static_assert(UNIT(1) <=> UNIT(2) == std::strong_ordering::less, ""); \ + static_assert(UNIT(1) <=> UNIT(2) == std::strong_ordering::less, ""); \ static_assert(UNIT(3) <=> UNIT(2) == std::strong_ordering::greater, ""); TEST_REL_OPS(absl::Nanoseconds); @@ -1159,8 +1157,7 @@ EXPECT_EQ(0, absl::Nanoseconds(-1) / absl::Seconds(1)); // Actual -1e-9 // Tests identity a = (a/b)*b + a%b -#define TEST_MOD_IDENTITY(a, b) \ - EXPECT_EQ((a), ((a) / (b))*(b) + ((a)%(b))) +#define TEST_MOD_IDENTITY(a, b) EXPECT_EQ((a), ((a) / (b)) * (b) + ((a) % (b))) TEST_MOD_IDENTITY(absl::Seconds(0), absl::Seconds(2)); TEST_MOD_IDENTITY(absl::Seconds(1), absl::Seconds(1));
diff --git a/absl/time/time.cc b/absl/time/time.cc index d983c12..faef864 100644 --- a/absl/time/time.cc +++ b/absl/time/time.cc
@@ -249,8 +249,8 @@ int64_t ToUnixNanos(Time t) { if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 && time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 33 == 0) { - return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * - 1000 * 1000 * 1000) + + return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * 1000 * + 1000 * 1000) + (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4); } return FloorToUnit(time_internal::ToUnixDuration(t), absl::Nanoseconds(1)); @@ -259,8 +259,8 @@ int64_t ToUnixMicros(Time t) { if (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >= 0 && time_internal::GetRepHi(time_internal::ToUnixDuration(t)) >> 43 == 0) { - return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * - 1000 * 1000) + + return (time_internal::GetRepHi(time_internal::ToUnixDuration(t)) * 1000 * + 1000) + (time_internal::GetRepLo(time_internal::ToUnixDuration(t)) / 4000); } return FloorToUnit(time_internal::ToUnixDuration(t), absl::Microseconds(1));
diff --git a/absl/time/time.h b/absl/time/time.h index 29beaac..8e8df2e 100644 --- a/absl/time/time.h +++ b/absl/time/time.h
@@ -732,7 +732,6 @@ // `absl::ParseDuration()`. bool AbslParseFlag(absl::string_view text, Duration* dst, std::string* error); - // AbslUnparseFlag() // // Unparses a Duration value into a command-line string representation using @@ -1681,14 +1680,16 @@ return (v <= (std::numeric_limits<int64_t>::max)() / 60 && v >= (std::numeric_limits<int64_t>::min)() / 60) ? MakeDuration(v * 60) - : v > 0 ? InfiniteDuration() : -InfiniteDuration(); + : v > 0 ? InfiniteDuration() + : -InfiniteDuration(); } ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration FromInt64(int64_t v, std::ratio<3600>) { return (v <= (std::numeric_limits<int64_t>::max)() / 3600 && v >= (std::numeric_limits<int64_t>::min)() / 3600) ? MakeDuration(v * 3600) - : v > 0 ? InfiniteDuration() : -InfiniteDuration(); + : v > 0 ? InfiniteDuration() + : -InfiniteDuration(); } // IsValidRep64<T>(0) is true if the expression `int64_t{std::declval<T>()}` is @@ -1806,13 +1807,12 @@ (std::numeric_limits<int64_t>::min)() ? InfiniteDuration() : time_internal::MakeDuration(-time_internal::GetRepHi(d)) - : time_internal::IsInfiniteDuration(d) - ? time_internal::OppositeInfinity(d) - : time_internal::MakeDuration( - time_internal::NegateAndSubtractOne( - time_internal::GetRepHi(d)), - time_internal::kTicksPerSecond - - time_internal::GetRepLo(d)); + : time_internal::IsInfiniteDuration(d) + ? time_internal::OppositeInfinity(d) + : time_internal::MakeDuration( + time_internal::NegateAndSubtractOne( + time_internal::GetRepHi(d)), + time_internal::kTicksPerSecond - time_internal::GetRepLo(d)); } ABSL_ATTRIBUTE_CONST_FUNCTION constexpr Duration InfiniteDuration() {
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index 7033326..6714a27 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc
@@ -13,6 +13,7 @@ // limitations under the License. #include "absl/time/time.h" + #include "absl/time/civil_time.h" #if defined(_MSC_VER)