diff --git a/MODULE.bazel b/MODULE.bazel index 6dfccce..00ab4c3 100644 --- a/MODULE.bazel +++ b/MODULE.bazel
@@ -26,8 +26,8 @@ ) use_repo(cc_configure, "local_config_cc") -bazel_dep(name = "rules_cc", version = "0.2.18") -bazel_dep(name = "bazel_skylib", version = "1.9.0") +bazel_dep(name = "rules_cc", version = "0.2.22") +bazel_dep(name = "bazel_skylib", version = "1.9.2") bazel_dep(name = "platforms", version = "1.1.0") bazel_dep( @@ -40,7 +40,7 @@ # intended to be used by Abseil users depend on GoogleTest. bazel_dep( name = "googletest", - version = "1.17.0.bcr.2", + version = "1.18.0", ) # Note: Gloop is NOT a dev_dependency, but should never be used directly. It is only included here
diff --git a/absl/base/attributes.h b/absl/base/attributes.h index bd43e66..6ec0446 100644 --- a/absl/base/attributes.h +++ b/absl/base/attributes.h
@@ -639,47 +639,16 @@ // // Annotates implicit fall-through between switch labels, allowing a case to // indicate intentional fallthrough and turn off warnings about any lack of a -// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by -// a semicolon and can be used in most places where `break` can, provided that -// no statements exist between it and the next switch label. +// `break` statement. // -// Example: +// Deprecated: Use the standard C++17 `[[fallthrough]]` instead. // -// switch (x) { -// case 40: -// case 41: -// if (truth_is_out_there) { -// ++x; -// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations -// // in comments -// } else { -// return x; -// } -// case 42: -// ... -// -// Notes: When supported, GCC and Clang can issue a warning on switch labels -// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See -// clang documentation on language extensions for details: -// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough -// -// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has -// no effect on diagnostics. In any case this macro has no effect on runtime -// behavior and performance of code. +// This macro has no effect on runtime behavior and performance of code. #ifdef ABSL_FALLTHROUGH_INTENDED #error "ABSL_FALLTHROUGH_INTENDED should not be defined." -#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -#else -#define ABSL_FALLTHROUGH_INTENDED \ - do { \ - } while (0) #endif +#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] // ABSL_DEPRECATED() //
diff --git a/absl/base/casts.h b/absl/base/casts.h index 8aac0da..17cc0b9 100644 --- a/absl/base/casts.h +++ b/absl/base/casts.h
@@ -30,11 +30,9 @@ #include <typeinfo> #include <utility> -#ifdef __has_include #if __has_include(<version>) #include <version> // For __cpp_lib_bit_cast. #endif -#endif #if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L #include <bit> // For std::bit_cast.
diff --git a/absl/base/config.h b/absl/base/config.h index 4a35ff1..e3e2c96 100644 --- a/absl/base/config.h +++ b/absl/base/config.h
@@ -241,41 +241,6 @@ #define ABSL_HAVE_TLS 1 #endif -// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE -// -// Checks whether `std::is_trivially_destructible<T>` is supported. -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE -#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set -#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 -#endif - -// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -// -// Checks whether `std::is_trivially_default_constructible<T>` and -// `std::is_trivially_copy_constructible<T>` are supported. -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE -#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set -#else -#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 -#endif - -// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE -// -// Checks whether `std::is_trivially_copy_assignable<T>` is supported. -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE -#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot be directly set -#else -#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 -#endif - -// ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE -// -// Checks whether `std::is_trivially_copyable<T>` is supported. -#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE -#error ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set -#define ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1 -#endif - // ABSL_HAVE_THREAD_LOCAL // // Checks whether the `thread_local` storage duration specifier is supported. @@ -512,14 +477,9 @@ __cpp_lib_source_location >= 201907L) || \ (defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \ ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L) -#ifdef __has_include #if __has_include(<source_location>) #define ABSL_HAVE_STD_SOURCE_LOCATION 1 #endif -#else -// No __has_include support, so just assume C++ language version is correct. -#define ABSL_HAVE_STD_SOURCE_LOCATION 1 -#endif #endif // ABSL_USES_STD_SOURCE_LOCATION @@ -709,17 +669,6 @@ #define ABSL_HAVE_LEAK_SANITIZER 1 #endif -// ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION -// -// Deprecated: always defined to 1. -// Class template argument deduction is a language feature added in C++17, -// which means all versions of C++ supported by Abseil have it. -#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION -#error "ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION cannot be directly set." -#else -#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 -#endif - // `ABSL_INTERNAL_HAS_RTTI` determines whether abseil is being compiled with // RTTI support. #ifdef ABSL_INTERNAL_HAS_RTTI
diff --git a/absl/base/const_init.h b/absl/base/const_init.h index 16520b6..28dee6f 100644 --- a/absl/base/const_init.h +++ b/absl/base/const_init.h
@@ -30,8 +30,8 @@ // undefined behavior, unless their constructors and destructors are designed // with this issue in mind. // -// The normal way to deal with this issue in C++11 is to use constant -// initialization and trivial destructors. +// The normal way to deal with this issue is to use constant initialization and +// trivial destructors. // // Constant initialization is guaranteed to occur before any other code // executes. Constructors that are declared 'constexpr' are eligible for
diff --git a/absl/base/internal/cpu_detect.cc b/absl/base/internal/cpu_detect.cc index 070cc86..a939bbf 100644 --- a/absl/base/internal/cpu_detect.cc +++ b/absl/base/internal/cpu_detect.cc
@@ -26,7 +26,7 @@ #endif #if defined(__aarch64__) && defined(__APPLE__) -#if defined(__has_include) && __has_include(<arm/cpu_capabilities_public.h>) +#if __has_include(<arm/cpu_capabilities_public.h>) #include <arm/cpu_capabilities_public.h> #endif #include <sys/sysctl.h>
diff --git a/absl/base/internal/strerror.cc b/absl/base/internal/strerror.cc index 519b93f..e9c4c23 100644 --- a/absl/base/internal/strerror.cc +++ b/absl/base/internal/strerror.cc
@@ -61,7 +61,7 @@ } // kSysNerr is the number of errors from a recent glibc. `StrError()` falls back -// to `StrErrorAdaptor()` if the value is larger than this. +// to `StrErrorInternal()` if the value is larger than this. constexpr int kSysNerr = 135; std::array<std::string, kSysNerr>* NewStrErrorTable() {
diff --git a/absl/base/internal/tsan_mutex_interface.h b/absl/base/internal/tsan_mutex_interface.h index 39207d8..e2d3d93 100644 --- a/absl/base/internal/tsan_mutex_interface.h +++ b/absl/base/internal/tsan_mutex_interface.h
@@ -16,6 +16,8 @@ // It provides ThreadSanitizer annotations for custom mutexes. // See <sanitizer/tsan_interface.h> for meaning of these annotations. +// SKIP_ABSL_INLINE_NAMESPACE_CHECK + #ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ #define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ @@ -30,11 +32,10 @@ #error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set." #endif -#if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include) -#if __has_include(<sanitizer/tsan_interface.h>) +#if defined(ABSL_HAVE_THREAD_SANITIZER) && \ + __has_include(<sanitizer/tsan_interface.h>) #define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1 #endif -#endif #ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE #include <sanitizer/tsan_interface.h>
diff --git a/absl/base/macros.h b/absl/base/macros.h index c435ebc..69463f3 100644 --- a/absl/base/macros.h +++ b/absl/base/macros.h
@@ -116,10 +116,9 @@ // ABSL_ASSERT() // -// In C++11, `assert` can't be used portably within constexpr functions. -// `assert` also generates spurious unused-symbol warnings. -// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr -// functions, and maintains references to symbols. Example: +// `assert` generates spurious unused-symbol warnings when NDEBUG is defined. +// ABSL_ASSERT functions as a runtime assert but maintains references to +// symbols even under NDEBUG. Example: // // constexpr double Divide(double a, double b) { // return ABSL_ASSERT(b != 0), a / b;
diff --git a/absl/base/policy_checks.h b/absl/base/policy_checks.h index 88b5774..45fe3d5 100644 --- a/absl/base/policy_checks.h +++ b/absl/base/policy_checks.h
@@ -52,7 +52,7 @@ #error "This package requires Visual Studio 2022 (MSVC++ 17.0) or higher." #endif -// We support GCC 7 and later. +// We support GCC 10 and later. // This minimum will go up. #if defined(__GNUC__) && !defined(__clang__) #if __GNUC__ < 10
diff --git a/absl/base/spinlock_test_common.cc b/absl/base/spinlock_test_common.cc index 6ac2e36..411150a 100644 --- a/absl/base/spinlock_test_common.cc +++ b/absl/base/spinlock_test_common.cc
@@ -127,7 +127,7 @@ } #ifndef ABSL_HAVE_THREAD_SANITIZER -static_assert(std::is_trivially_destructible<SpinLock>(), ""); +static_assert(std::is_trivially_destructible<SpinLock>()); #endif TEST(SpinLock, StackNonCooperativeDisablesScheduling) {
diff --git a/absl/cleanup/cleanup_test.cc b/absl/cleanup/cleanup_test.cc index 0d407b2..a413b7e 100644 --- a/absl/cleanup/cleanup_test.cc +++ b/absl/cleanup/cleanup_test.cc
@@ -97,22 +97,19 @@ auto cleanup = absl::MakeCleanup(std::move(callback)); static_assert( - IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(), - ""); + IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>()); } { auto cleanup = absl::MakeCleanup(&FnPtrFunction); - static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), - ""); + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>()); } { auto cleanup = absl::MakeCleanup(FnPtrFunction); - static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), - ""); + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>()); } } @@ -122,22 +119,19 @@ absl::Cleanup cleanup = std::move(callback); static_assert( - IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(), - ""); + IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>()); } { absl::Cleanup cleanup = &FnPtrFunction; - static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), - ""); + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>()); } { absl::Cleanup cleanup = FnPtrFunction; - static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(), - ""); + static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>()); } } @@ -148,7 +142,7 @@ absl::Cleanup deduction_cleanup = callback; static_assert( - IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>()); } { @@ -157,7 +151,7 @@ absl::Cleanup deduction_cleanup = FunctorClassFactory::AsCallback([] {}); static_assert( - IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>()); } { @@ -166,7 +160,7 @@ absl::Cleanup deduction_cleanup = StdFunctionFactory::AsCallback([] {}); static_assert( - IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>()); } { @@ -174,7 +168,7 @@ absl::Cleanup deduction_cleanup = &FnPtrFunction; static_assert( - IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>()); } { @@ -182,7 +176,7 @@ absl::Cleanup deduction_cleanup = FnPtrFunction; static_assert( - IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), ""); + IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>()); } }
diff --git a/absl/container/btree_map.h b/absl/container/btree_map.h index aaef5bb..257a624 100644 --- a/absl/container/btree_map.h +++ b/absl/container/btree_map.h
@@ -371,11 +371,6 @@ // does not contain an element with a matching key, this function returns an // empty node handle. // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). - // // NOTE: In this context, `node_type` refers to the C++17 concept of a // move-only type that owns and provides access to the elements in associative // containers (https://en.cppreference.com/w/cpp/container/node_handle). @@ -737,11 +732,6 @@ // does not contain an element with a matching key, this function returns an // empty node handle. // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). - // // NOTE: In this context, `node_type` refers to the C++17 concept of a // move-only type that owns and provides access to the elements in associative // containers (https://en.cppreference.com/w/cpp/container/node_handle).
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc index b2e1f4c..5b76c34 100644 --- a/absl/container/btree_test.cc +++ b/absl/container/btree_test.cc
@@ -3530,7 +3530,7 @@ // This breaks if we try to do layout_type::Pointer<slot_type> because // slot_type is the same as field_type. using set_type = absl::btree_set<uint8_t>; - static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>(), ""); + static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>()); TestBasicFunctionality(set_type()); }
diff --git a/absl/container/chunked_queue.h b/absl/container/chunked_queue.h index 0e686ca..8ada208 100644 --- a/absl/container/chunked_queue.h +++ b/absl/container/chunked_queue.h
@@ -573,12 +573,6 @@ }; template <typename T, size_t BLo, size_t BHi, typename Allocator> -constexpr size_t chunked_queue<T, BLo, BHi, Allocator>::kBlockSizeMin; - -template <typename T, size_t BLo, size_t BHi, typename Allocator> -constexpr size_t chunked_queue<T, BLo, BHi, Allocator>::kBlockSizeMax; - -template <typename T, size_t BLo, size_t BHi, typename Allocator> inline void swap(chunked_queue<T, BLo, BHi, Allocator>& a, chunked_queue<T, BLo, BHi, Allocator>& b) noexcept { a.swap(b);
diff --git a/absl/container/fixed_array.h b/absl/container/fixed_array.h index 48ac57f..713c685 100644 --- a/absl/container/fixed_array.h +++ b/absl/container/fixed_array.h
@@ -430,8 +430,8 @@ return std::addressof(ptr->array); } - static_assert(sizeof(StorageElement) == sizeof(value_type), ""); - static_assert(alignof(StorageElement) == alignof(value_type), ""); + static_assert(sizeof(StorageElement) == sizeof(value_type)); + static_assert(alignof(StorageElement) == alignof(value_type)); class NonEmptyInlinedStorage { public:
diff --git a/absl/container/flat_hash_map.h b/absl/container/flat_hash_map.h index f8c3ba7..b434a47 100644 --- a/absl/container/flat_hash_map.h +++ b/absl/container/flat_hash_map.h
@@ -439,11 +439,6 @@ // key value and returns a node handle owning that extracted data. If the // `flat_hash_map` does not contain an element with a matching key, this // function returns an empty node handle. - // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). using Base::extract; // flat_hash_map::merge()
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc index effbae3..213cb70 100644 --- a/absl/container/flat_hash_map_test.cc +++ b/absl/container/flat_hash_map_test.cc
@@ -66,7 +66,7 @@ using Map = flat_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual, Alloc<std::pair<const K, V>>>; -static_assert(!std::is_standard_layout<NonStandardLayout>(), ""); +static_assert(!std::is_standard_layout<NonStandardLayout>()); using MapTypes = ::testing::Types<Map<int, int>, Map<std::string, int>, @@ -92,7 +92,7 @@ bool operator==(const Int& other) const { return value == other.value; } size_t value; }; - static_assert(std::is_standard_layout<Int>(), ""); + static_assert(std::is_standard_layout<Int>()); struct Hash { size_t operator()(const Int& obj) const { return obj.value; }
diff --git a/absl/container/inlined_vector.h b/absl/container/inlined_vector.h index 2694a5d..8dfbf03 100644 --- a/absl/container/inlined_vector.h +++ b/absl/container/inlined_vector.h
@@ -893,8 +893,8 @@ // Assumption check: we shouldn't be told to use memcpy to implement move // assignment unless we have trivially destructible elements and an // allocator that does nothing fancy. - static_assert(std::is_trivially_destructible_v<value_type>, ""); - static_assert(std::is_same_v<A, std::allocator<value_type>>, ""); + static_assert(std::is_trivially_destructible_v<value_type>); + static_assert(std::is_same_v<A, std::allocator<value_type>>); // Throw away our existing heap allocation, if any. There is no need to // destroy the existing elements one by one because we know they are
diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index 5f5b66b..55ff457 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h
@@ -97,7 +97,8 @@ #endif template <typename Compare, typename T, typename U> -using compare_result_t = absl::result_of_t<const Compare(const T &, const U &)>; +using compare_result_t = + std::invoke_result_t<const Compare, const T &, const U &>; // A helper class that indicates if the Compare parameter is a key-compare-to // comparator.
diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h index 429bf31..b2839e6 100644 --- a/absl/container/internal/common.h +++ b/absl/container/internal/common.h
@@ -194,8 +194,6 @@ constexpr node_handle() {} - // When C++17 is available, we can use std::launder to provide mutable - // access to the key. Otherwise, we provide const access. auto key() const -> decltype(PolicyTraits::mutable_key(std::declval<slot_type*>())) { return PolicyTraits::mutable_key(this->slot());
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h index 81346f9..1d361f5 100644 --- a/absl/container/internal/container_memory.h +++ b/absl/container/internal/container_memory.h
@@ -60,7 +60,7 @@ // returns insufficiently alignment pointer, that's what you are going to get. template <size_t Alignment, class Alloc> void* Allocate(Alloc* alloc, size_t n) { - static_assert(Alignment > 0, ""); + static_assert(Alignment > 0); assert(n && "n must be positive"); using M = AlignedType<Alignment>; using A = typename std::allocator_traits<Alloc>::template rebind_alloc<M>; @@ -91,7 +91,7 @@ // Allocate<Alignment>(alloc, n). template <size_t Alignment, class Alloc> void Deallocate(Alloc* alloc, void* p, size_t n) { - static_assert(Alignment > 0, ""); + static_assert(Alignment > 0); assert(n && "n must be positive"); using M = AlignedType<Alignment>; using A = typename std::allocator_traits<Alloc>::template rebind_alloc<M>;
diff --git a/absl/container/internal/hashtable_control_bytes.h b/absl/container/internal/hashtable_control_bytes.h index fd4dea4..b0faec3 100644 --- a/absl/container/internal/hashtable_control_bytes.h +++ b/absl/container/internal/hashtable_control_bytes.h
@@ -125,9 +125,9 @@ bool NullifyBitsOnIteration = false> class BitMask : public NonIterableBitMask<T, SignificantBits, Shift> { using Base = NonIterableBitMask<T, SignificantBits, Shift>; - static_assert(std::is_unsigned_v<T>, ""); - static_assert(Shift == 0 || Shift == 3, ""); - static_assert(!NullifyBitsOnIteration || Shift == 3, ""); + static_assert(std::is_unsigned_v<T>); + static_assert(Shift == 0 || Shift == 3); + static_assert(!NullifyBitsOnIteration || Shift == 3); public: explicit BitMask(T mask) : Base(mask) {
diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index e6491ba..5b9763e 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h
@@ -76,7 +76,7 @@ template <typename A> using IsMoveAssignOk = std::is_move_assignable<ValueType<A>>; template <typename A> -using IsSwapOk = absl::type_traits_internal::IsSwappable<ValueType<A>>; +using IsSwapOk = std::is_swappable<ValueType<A>>; template <typename A, bool IsTriviallyDestructible = std::is_trivially_destructible_v<ValueType<A>> &&
diff --git a/absl/container/internal/layout.h b/absl/container/internal/layout.h index fac7d81..a4cfe59 100644 --- a/absl/container/internal/layout.h +++ b/absl/container/internal/layout.h
@@ -317,11 +317,10 @@ // Can `T` be a template argument of `Layout`? template <class T> using IsLegalElementType = - std::integral_constant<bool, - !std::is_reference_v<T> && !std::is_volatile_v<T> && - !std::is_reference_v<typename Type<T>::type> && - !std::is_volatile_v<typename Type<T>::type> && - adl_barrier::IsPow2(AlignOf<T>::value)>; + std::bool_constant<!std::is_reference_v<T> && !std::is_volatile_v<T> && + !std::is_reference_v<typename Type<T>::type> && + !std::is_volatile_v<typename Type<T>::type> && + adl_barrier::IsPow2(AlignOf<T>::value)>; template <class Elements, class StaticSizeSeq, class RuntimeSizeSeq, class SizeSeq, class OffsetSeq> @@ -739,8 +738,7 @@ // Requires: all arguments are convertible to `size_t`. template <class... Sizes> static constexpr PartialType<sizeof...(Sizes)> Partial(Sizes&&... sizes) { - static_assert(sizeof...(Sizes) + StaticSizeSeq::size() <= sizeof...(Ts), - ""); + static_assert(sizeof...(Sizes) + StaticSizeSeq::size() <= sizeof...(Ts)); return PartialType<sizeof...(Sizes)>( static_cast<size_t>(std::forward<Sizes>(sizes))...); }
diff --git a/absl/container/internal/layout_test.cc b/absl/container/internal/layout_test.cc index e99c56a..d2d1196 100644 --- a/absl/container/internal/layout_test.cc +++ b/absl/container/internal/layout_test.cc
@@ -50,7 +50,7 @@ template <class Expected, class Actual> Expected Type(Actual val) { - static_assert(std::is_same<Expected, Actual>(), ""); + static_assert(std::is_same<Expected, Actual>()); return val; } @@ -73,20 +73,20 @@ }; // Properties of types that this test relies on. -static_assert(sizeof(int8_t) == 1, ""); -static_assert(alignof(int8_t) == 1, ""); -static_assert(sizeof(int16_t) == 2, ""); -static_assert(alignof(int16_t) == 2, ""); -static_assert(sizeof(int32_t) == 4, ""); -static_assert(alignof(int32_t) == 4, ""); -static_assert(sizeof(Int64) == 8, ""); -static_assert(alignof(Int64) == 8, ""); -static_assert(sizeof(Int128) == 16, ""); -static_assert(alignof(Int128) == 8, ""); +static_assert(sizeof(int8_t) == 1); +static_assert(alignof(int8_t) == 1); +static_assert(sizeof(int16_t) == 2); +static_assert(alignof(int16_t) == 2); +static_assert(sizeof(int32_t) == 4); +static_assert(alignof(int32_t) == 4); +static_assert(sizeof(Int64) == 8); +static_assert(alignof(Int64) == 8); +static_assert(sizeof(Int128) == 16); +static_assert(alignof(Int128) == 8); template <class Expected, class Actual> void SameType() { - static_assert(std::is_same<Expected, Actual>(), ""); + static_assert(std::is_same<Expected, Actual>()); } TEST(Layout, ElementType) { @@ -1435,7 +1435,7 @@ template <typename Tuple> bool MatchAndExplain(const Tuple& p, testing::MatchResultListener* /* listener */) const { - static_assert(std::tuple_size<Tuple>::value == sizeof...(M), ""); + static_assert(std::tuple_size<Tuple>::value == sizeof...(M)); return MatchAndExplainImpl( p, std::make_index_sequence<std::tuple_size<Tuple>::value>{}); } @@ -1597,52 +1597,50 @@ } TEST(Layout, Alignment) { - static_assert(Layout<int8_t>::Alignment() == 1, ""); - static_assert(Layout<int32_t>::Alignment() == 4, ""); - static_assert(Layout<Int64>::Alignment() == 8, ""); - static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, ""); - static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, ""); - static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, ""); - static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, ""); - static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, ""); - static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, ""); - static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, ""); - static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, ""); - static_assert( - Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, ""); - static_assert( - Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, ""); + static_assert(Layout<int8_t>::Alignment() == 1); + static_assert(Layout<int32_t>::Alignment() == 4); + static_assert(Layout<Int64>::Alignment() == 8); + static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64); + static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8); + static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8); + static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8); + static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8); + static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8); + static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8); + static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8); + static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == + 64); + static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == + 64); } TEST(Layout, StaticAlignment) { - static_assert(Layout<int8_t>::WithStaticSizes<>::Alignment() == 1, ""); - static_assert(Layout<int8_t>::WithStaticSizes<0>::Alignment() == 1, ""); - static_assert(Layout<int8_t>::WithStaticSizes<7>::Alignment() == 1, ""); - static_assert(Layout<int32_t>::WithStaticSizes<>::Alignment() == 4, ""); - static_assert(Layout<int32_t>::WithStaticSizes<0>::Alignment() == 4, ""); - static_assert(Layout<int32_t>::WithStaticSizes<3>::Alignment() == 4, ""); + static_assert(Layout<int8_t>::WithStaticSizes<>::Alignment() == 1); + static_assert(Layout<int8_t>::WithStaticSizes<0>::Alignment() == 1); + static_assert(Layout<int8_t>::WithStaticSizes<7>::Alignment() == 1); + static_assert(Layout<int32_t>::WithStaticSizes<>::Alignment() == 4); + static_assert(Layout<int32_t>::WithStaticSizes<0>::Alignment() == 4); + static_assert(Layout<int32_t>::WithStaticSizes<3>::Alignment() == 4); + static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == + 64); + static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<0>::Alignment() == + 64); + static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == + 64); static_assert( - Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, ""); - static_assert( - Layout<Aligned<int8_t, 64>>::WithStaticSizes<0>::Alignment() == 64, ""); - static_assert( - Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, ""); - static_assert( - Layout<int32_t, Int64, int8_t>::WithStaticSizes<>::Alignment() == 8, ""); + Layout<int32_t, Int64, int8_t>::WithStaticSizes<>::Alignment() == 8); static_assert( Layout<int32_t, Int64, int8_t>::WithStaticSizes<0, 0, 0>::Alignment() == - 8, - ""); + 8); static_assert( Layout<int32_t, Int64, int8_t>::WithStaticSizes<1, 1, 1>::Alignment() == - 8, - ""); + 8); } TEST(Layout, ConstexprPartial) { constexpr size_t M = alignof(max_align_t); constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3); - static_assert(x.Partial(1).template Offset<1>() == 2 * M, ""); + static_assert(x.Partial(1).template Offset<1>() == 2 * M); } TEST(Layout, StaticConstexpr) { @@ -1650,7 +1648,7 @@ using L = Layout<unsigned char, Aligned<unsigned char, 2 * M>>; using SL = L::WithStaticSizes<1, 3>; constexpr SL x; - static_assert(x.Offset<1>() == 2 * M, ""); + static_assert(x.Offset<1>() == 2 * M); } // [from, to)
diff --git a/absl/container/internal/node_slot_policy.h b/absl/container/internal/node_slot_policy.h index 7213dda..4a7dca2 100644 --- a/absl/container/internal/node_slot_policy.h +++ b/absl/container/internal/node_slot_policy.h
@@ -47,7 +47,7 @@ template <class Reference, class Policy> struct node_slot_policy { - static_assert(std::is_lvalue_reference_v<Reference>, ""); + static_assert(std::is_lvalue_reference_v<Reference>); using slot_type = std::remove_cv_t<std::remove_reference_t<Reference>>*;
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index 04e9e61..8301b50 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h
@@ -95,11 +95,11 @@ using key_type = typename Policy::key_type; using mapped_type = typename Policy::mapped_type; - static_assert(!std::is_reference_v<key_type>, ""); + static_assert(!std::is_reference_v<key_type>); // TODO(b/187807849): Evaluate whether to support reference mapped_type and // remove this assertion if/when it is supported. - static_assert(!std::is_reference_v<mapped_type>, ""); + static_assert(!std::is_reference_v<mapped_type>); using iterator = typename raw_hash_map::raw_hash_set::iterator; using const_iterator = typename raw_hash_map::raw_hash_set::const_iterator;
diff --git a/absl/container/internal/raw_hash_set.cc b/absl/container/internal/raw_hash_set.cc index d37c781..3f9263c 100644 --- a/absl/container/internal/raw_hash_set.cc +++ b/absl/container/internal/raw_hash_set.cc
@@ -141,9 +141,8 @@ // Must be defined out-of-line to avoid MSVC error C2482 on some platforms, // which is caused by non-constexpr initialization. -uint16_t NextHashTableSeed() { - static_assert(PerTableSeed::kBitCount <= 16); - return static_cast<uint16_t>(RandomSeed()); +uint8_t NextHashTableSeed() { + return static_cast<uint8_t>(RandomSeed()); } GenerationType* EmptyGeneration() { @@ -943,6 +942,7 @@ destroy_slot(&c, SingleSlotAddress<kSooEnabled>(c)); } DecrementSmallSize<kSooEnabled>(c); + c.infoz().RecordStorageChanged(0, cap); } } else { if (destroy_slot != nullptr) { @@ -2289,7 +2289,10 @@ const size_t slot_size = policy.slot_size; const bool soo_enabled = policy.soo_enabled; if (size == 1) { - if (!soo_enabled) ReserveTableToFitNewSize(common, policy, 1); + if (!soo_enabled) { + ReserveEmptyNonAllocatedTableToFitNewSize(common, policy, 1); + common.infoz().RecordStorageChanged(1, 1); + } IncrementSmallSize(common, policy); const size_t other_capacity = other.capacity(); const void* other_slot =
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 5a4fce8..0531300 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -568,7 +568,9 @@ // We use these sentinel capacity values in debug mode to indicate different // classes of bugs. enum InvalidCapacity : IntType { - kAboveMaxValidCapacity = (std::numeric_limits<IntType>::max)() - 100, + kAboveMaxValidCapacity = StorageMode == kCapacityByValue + ? (std::numeric_limits<IntType>::max)() - 100 + : 64 - 10, kReentrance, kDestroyed, @@ -590,39 +592,24 @@ class HashtableInlineDataImpl; // Returns next per-table seed. -uint16_t NextHashTableSeed(); +uint8_t NextHashTableSeed(); // Per table hash salt. This gets mixed into H1 to randomize iteration order // per-table. // The seed is needed to ensure non-determinism of iteration order. -template <typename StorageType> -class PerTableSeedImpl { +class PerTableSeed { public: - using IntType = StorageType; - - // The number of bits in the seed. - // It is big enough to ensure non-determinism of iteration order. - // We store the seed inside a uint64_t together with size and other metadata. - // Using 8 or 16 bits allows us to save one `and` instruction in H1 (we use - // zero-extended move instead of mov+and). When absl::Hash is inlined, it can - // also have lower latency knowing that the high bits of the seed are zero. - static constexpr size_t kBitCount = sizeof(IntType) * 8; - - // We need to use a constant seed when the table is sampled so that sampled - // hashes use the same seed and can e.g. identify stuck bits accurately. - static constexpr IntType kSampledSeed = static_cast<IntType>(~IntType{0}); - // Returns the seed for the table. size_t seed() const { return seed_; } private: - template <HashtableCapacityStorageMode StorageMode> + template <HashtableCapacityStorageMode StorageModeOfData> friend class HashtableInlineDataImpl; - explicit PerTableSeedImpl(uint64_t seed) - : seed_(static_cast<IntType>(seed)) {} + explicit PerTableSeed(uint64_t seed) + : seed_(static_cast<uint16_t>(seed)) {} - const IntType seed_; + const uint16_t seed_; }; // Represents blocked elements info: log2_period and tail_blocked. @@ -672,18 +659,25 @@ // bit of the seed is repurposed to track if sampling has been tried). template <HashtableCapacityStorageMode StorageMode> class HashtableInlineDataImpl { + // The number of bits in the seed. It is big enough to ensure + // non-determinism of iteration order. We store the seed inside a uint64_t + // together with size and other metadata. When absl::Hash is inlined, it can + // have lower latency knowing that the high bits of the seed are zero. + static constexpr size_t kSeedBitCount = 5; + public: static constexpr HashtableCapacityStorageMode kStorageMode = StorageMode; - using PerTableSeed = PerTableSeedImpl< - std::conditional_t<StorageMode == kCapacityByValue, uint16_t, uint8_t>>; using HashtableCapacity = HashtableCapacityImpl<StorageMode>; static constexpr size_t kBlockedElementBitCount = 3; static constexpr size_t kMaxBlockedElementCount = (uint64_t{1} << kBlockedElementBitCount) - 1; + static constexpr size_t kCapacityBitCount = + StorageMode == kCapacityByValue ? sizeof(HashtableCapacity) * 8 : 6; + static constexpr size_t kCapacityBitStoredInDataCount = + StorageMode == kCapacityByValue ? 0 : kCapacityBitCount; static constexpr size_t kSizeBitCount = - 64 - - (kBlockedElementBitCount + PerTableSeed::kBitCount + /*has_infoz*/ 1 + - (StorageMode == kCapacityByValue ? 0 : sizeof(HashtableCapacity) * 8)); + 64 - (kBlockedElementBitCount + kSeedBitCount + + /*has_infoz*/ 1 + kCapacityBitStoredInDataCount); explicit HashtableInlineDataImpl(uninitialized_tag_t) {} explicit HashtableInlineDataImpl(HashtableCapacity capacity, @@ -727,18 +721,18 @@ (data_ & kMetadataMask) | (static_cast<uint64_t>(size) << kSizeShift); } - PerTableSeed seed() const { return PerTableSeed(data_ & kSeedMask); } - - void generate_new_seed() { - set_seed(static_cast<typename PerTableSeed::IntType>(NextHashTableSeed())); + PerTableSeed seed() const { + return PerTableSeed(ToPublicSeed(data_ & kSeedMask)); } + void generate_new_seed() { set_seed(NextHashTableSeed()); } + // We need to use a constant seed when the table is sampled so that sampled // hashes use the same seed and can e.g. identify stuck bits accurately. - void set_sampled_seed() { set_seed(PerTableSeed::kSampledSeed); } + void set_sampled_seed() { set_seed(kSampledSeed); } bool is_sampled_seed() const { - return seed().seed() == PerTableSeed::kSampledSeed; + return seed().seed() == ToPublicSeed(kSampledSeed); } // Returns true if the table has infoz. @@ -767,34 +761,46 @@ void set_no_seed_for_testing() { data_ &= ~kSeedMask; } private: - // Bit layout of `data_` from MSB to LSB: - // (44 bits) : size + // Bit layout of `data_` and `capacity_internal_` from MSB to LSB: + // (55/49 bits) : size // (3 bits) : blocked_element_count // (1 bit) : has_infoz - // (16 or 8 bits) : seed + // (5 bits) : seed + // (6 bits) : capacity (only for kCapacityByLog) // We don't split these components of `data_` into separate bit field elements // because we get worse generated code that way. + static constexpr size_t kDataBitCount = - PerTableSeed::kBitCount + 1 + kSizeBitCount + kBlockedElementBitCount; + kSeedBitCount + 1 + kSizeBitCount + kBlockedElementBitCount; static constexpr size_t kSizeShift = kDataBitCount - kSizeBitCount; static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift; static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1; - static constexpr uint64_t kSeedMask = - (uint64_t{1} << PerTableSeed::kBitCount) - 1; + static constexpr uint64_t kSeedMask = (uint64_t{1} << kSeedBitCount) - 1; // The next bit after the seed. static constexpr uint64_t kHasInfozMask = kSeedMask + 1; - static constexpr uint64_t kBlockedElementsShift = PerTableSeed::kBitCount + 1; + static constexpr uint64_t kBlockedElementsShift = kSeedBitCount + 1; static constexpr uint64_t kBlockedElementMask = kMaxBlockedElementCount << kBlockedElementsShift; // For SOO tables, the seed is unused, and bit 0 is repurposed to track // whether the table has already queried should_sample_soo(). static constexpr uint64_t kSooHasTriedSamplingMask = 1; - void set_seed(typename PerTableSeed::IntType seed) { - data_ = (data_ & ~kSeedMask) | seed; + // We need to use a constant seed when the table is sampled so that sampled + // hashes use the same seed and can e.g. identify stuck bits accurately. + static constexpr uint8_t kSampledSeed = (1 << kSeedBitCount) - 1; + + static constexpr uint64_t ToPublicSeed(uint64_t seed) { + // In kCapacityByLog mode, we shift public seed to the left to keep bits of + // the seed in the original place. It allows us to use single instruction to + // access the seed (e.g., `andl $0x7c0, %r8d`). + return seed << kCapacityBitStoredInDataCount; } - uint64_t capacity_internal_ : sizeof(HashtableCapacity) * 8; + void set_seed(uint8_t seed) { + data_ = (data_ & ~kSeedMask) | (seed & kSeedMask); + } + + uint64_t capacity_internal_ : kCapacityBitCount; uint64_t data_ : kDataBitCount; }; @@ -814,7 +820,6 @@ #else using HashtableInlineData = HashtableInlineDataImpl<kCapacityByValue>; #endif // ABSL_SWISSTABLE_INTERNAL_ENABLE_CAPACITY_BY_VALUE -using PerTableSeed = HashtableInlineData::PerTableSeed; using HashtableCapacity = HashtableInlineData::HashtableCapacity; // For large tables, we limit the number of blocked elements to maintain O(1)
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc index 469341e..c52c692 100644 --- a/absl/container/internal/raw_hash_set_test.cc +++ b/absl/container/internal/raw_hash_set_test.cc
@@ -1352,8 +1352,8 @@ ChangingSizeAndTrackingTypeAlloc<int64_t>>; TEST(Table, EmptyFunctorOptimization) { - static_assert(std::is_empty_v<std::equal_to<absl::string_view>>, ""); - static_assert(std::is_empty_v<std::allocator<int>>, ""); + static_assert(std::is_empty_v<std::equal_to<absl::string_view>>); + static_assert(std::is_empty_v<std::allocator<int>>); struct MockTableByValue { size_t capacity; @@ -1545,13 +1545,12 @@ for (size_t capacity = 31; capacity < 256; capacity = NextCapacity(capacity)) { SCOPED_TRACE(absl::StrCat("capacity: ", capacity)); - // Number of elements we keep empty in order to force a rehash without + // Number of elements we reserve in order to force a rehash without // growth. RehashOrGrowToNextCapacityAndPrepareInsert grow if number of full - // slots is greater than 25/32 of capacity, so we leave 7/32 + 5 empty to - // have extra margin. - size_t empty_till_full = (capacity + 1) / 32 * 7 + 5; + // slots is greater than 25/32 of capacity. We reserve slightly less than + // 25/32 of capacity to have extra space for tombstones. int64_t reserve_size = - static_cast<int64_t>(CapacityToGrowth(capacity) - empty_till_full); + static_cast<int64_t>((capacity - 5) * 25 / 32 - 2); BadTwoValuesHashTable t( 0, @@ -1560,9 +1559,8 @@ // will be placed at the beginning of the table. BadTwoValuesHash(static_cast<size_t>(reserve_size))); // Remove seed to make table layout deterministic. - RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing(); - t.reserve(static_cast<size_t>(reserve_size)); + RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing(); for (int64_t i = 1; i <= reserve_size; ++i) { ASSERT_TRUE(t.insert(i * kCoef).second); } @@ -1632,10 +1630,9 @@ BadTwoValuesHashTable t(0, // Negative number goes to the end of the table. BadTwoValuesHash(kReserveSize + 2)); + t.reserve(kReserveSize); // Remove seed to make table layout deterministic. RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing(); - - t.reserve(kReserveSize); for (int64_t i = 0; i < static_cast<int64_t>(Group::kWidth); ++i) { ASSERT_TRUE(t.insert(i * kCoef).second); } @@ -4109,6 +4106,22 @@ } } +TEST(RawHashSamplerTest, NonSooTableRepeatedInsertClearCountSizeRight) { + ASSERT_EQ(NonSooIntTable().capacity(), 0); + std::vector<const HashtablezInfo*> infos = + SampleNonSooMutation([](NonSooIntTable& t) { + for (int i = 0; i < 10; ++i) { + t.insert(1); + t.clear(); + } + }); + for (const HashtablezInfo* info : infos) { + EXPECT_EQ(info->soo_capacity, 0); + ASSERT_EQ(info->capacity, 1); + ASSERT_EQ(info->size, 0); + } +} + // Verifies that copy-constructing or copy-assigning an SOO table does not // incorrectly trigger new sampling evaluations. TEST(RawHashSamplerTest, SooTableCopyDoesNotOversample) { @@ -4217,6 +4230,22 @@ } } +TEST(RawHashSamplerTest, NonSooTableSampleOnCopy) { + NonSooIntTable t_orig; + t_orig.insert(1); + + std::vector<const HashtablezInfo*> infos = + SampleNonSooMutation([&t_orig](NonSooIntTable& t) { t = t_orig; }); + + for (const HashtablezInfo* info : infos) { + ASSERT_EQ(info->inline_element_size, + sizeof(typename NonSooIntTable::value_type)); + ASSERT_EQ(info->soo_capacity, 0); + ASSERT_EQ(info->capacity, 1); + ASSERT_EQ(info->size, 1); + } +} + // This tests that rehash(0) on a sampled table with size that fits in SOO // doesn't incorrectly result in losing sampling. TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
diff --git a/absl/container/internal/unordered_set_lookup_test.h b/absl/container/internal/unordered_set_lookup_test.h index 2c9f57f..932c320 100644 --- a/absl/container/internal/unordered_set_lookup_test.h +++ b/absl/container/internal/unordered_set_lookup_test.h
@@ -52,11 +52,9 @@ for (const auto& v : values) { typename TypeParam::iterator it = m.find(v); static_assert( - std::is_same_v<const typename TypeParam::value_type&, decltype(*it)>, - ""); + std::is_same_v<const typename TypeParam::value_type&, decltype(*it)>); static_assert(std::is_same<const typename TypeParam::value_type*, - decltype(it.operator->())>::value, - ""); + decltype(it.operator->())>::value); EXPECT_TRUE(m.end() != it) << ::testing::PrintToString(v); EXPECT_EQ(v, *it) << ::testing::PrintToString(v); }
diff --git a/absl/container/linked_hash_map_test.cc b/absl/container/linked_hash_map_test.cc index e8df807..8b95c12 100644 --- a/absl/container/linked_hash_map_test.cc +++ b/absl/container/linked_hash_map_test.cc
@@ -53,7 +53,7 @@ using Map = linked_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual, Alloc<std::pair<const K, V>>>; -static_assert(!std::is_standard_layout<NonStandardLayout>(), ""); +static_assert(!std::is_standard_layout<NonStandardLayout>()); using MapTypes = ::testing::Types<Map<int, int>, Map<std::string, int>,
diff --git a/absl/container/node_hash_map.h b/absl/container/node_hash_map.h index d58feed..bd2f426 100644 --- a/absl/container/node_hash_map.h +++ b/absl/container/node_hash_map.h
@@ -428,10 +428,6 @@ // `node_hash_map` does not contain an element with a matching key, this // function returns an empty node handle. // - // NOTE: when compiled in an earlier version of C++ than C++17, - // `node_type::key()` returns a const reference to the key instead of a - // mutable reference. We cannot safely return a mutable reference without - // std::launder (which is not available before C++17). using Base::extract; // node_hash_map::merge()
diff --git a/absl/container/node_hash_map_test.cc b/absl/container/node_hash_map_test.cc index 107b329..476b12f 100644 --- a/absl/container/node_hash_map_test.cc +++ b/absl/container/node_hash_map_test.cc
@@ -196,7 +196,7 @@ // NonMovableKey is neither copyable nor movable. We should still be able to // move nodes around. - static_assert(!std::is_move_constructible_v<NonMovableKey>, ""); + static_assert(!std::is_move_constructible_v<NonMovableKey>); set1.merge(set2); EXPECT_THAT(set1,
diff --git a/absl/debugging/failure_signal_handler.cc b/absl/debugging/failure_signal_handler.cc index 46cb97f..745f773 100644 --- a/absl/debugging/failure_signal_handler.cc +++ b/absl/debugging/failure_signal_handler.cc
@@ -71,7 +71,7 @@ // Checks whether pthread_cpu_number_np is available. #ifdef ABSL_HAVE_PTHREAD_CPU_NUMBER_NP #error ABSL_HAVE_PTHREAD_CPU_NUMBER_NP cannot be directly set -#elif defined(__APPLE__) && defined(__has_include) && \ +#elif defined(__APPLE__) && \ ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000) || \ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
diff --git a/absl/debugging/internal/stacktrace_config.h b/absl/debugging/internal/stacktrace_config.h index c82d4a3..1ce2ad6 100644 --- a/absl/debugging/internal/stacktrace_config.h +++ b/absl/debugging/internal/stacktrace_config.h
@@ -18,6 +18,9 @@ * This header is "private" to stacktrace.cc. * DO NOT include it into any other files. */ + +// SKIP_ABSL_INLINE_NAMESPACE_CHECK + #ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_ #define ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_ @@ -59,7 +62,7 @@ #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_libunwind-inl.inc" #define STACKTRACE_USES_LIBUNWIND 1 -#elif defined(NO_FRAME_POINTER) && defined(__has_include) +#elif defined(NO_FRAME_POINTER) #if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL) // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ @@ -77,13 +80,13 @@ #elif defined(__riscv) #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_riscv-inl.inc" -#elif defined(__has_include) +#else #if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL) // Note: When using glibc this may require -funwind-tables to function properly. #define ABSL_STACKTRACE_INL_HEADER \ "absl/debugging/internal/stacktrace_generic-inl.inc" #endif // __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL) -#endif // defined(__has_include) +#endif #endif // defined(__linux__) && !defined(__ANDROID__)
diff --git a/absl/debugging/internal/vdso_support.cc b/absl/debugging/internal/vdso_support.cc index f7e2a44..d9dfccb 100644 --- a/absl/debugging/internal/vdso_support.cc +++ b/absl/debugging/internal/vdso_support.cc
@@ -21,10 +21,6 @@ #ifdef ABSL_HAVE_VDSO_SUPPORT // defined in vdso_support.h -#if !defined(__has_include) -#define __has_include(header) 0 -#endif - #include <errno.h> #include <fcntl.h> #if __has_include(<syscall.h>)
diff --git a/absl/debugging/stacktrace_test.cc b/absl/debugging/stacktrace_test.cc index 17552b4..0bf94f7 100644 --- a/absl/debugging/stacktrace_test.cc +++ b/absl/debugging/stacktrace_test.cc
@@ -312,7 +312,8 @@ const void* g_return_address = nullptr; bool g_sigusr2_raised = false; -void SigUsr2Handler(int, siginfo_t*, void* uc) { +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS void SigUsr2Handler(int, siginfo_t*, + void* uc) { absl::base_internal::ErrnoSaver errno_saver; // Many platforms don't support this by default. bool support_is_expected = false; @@ -333,18 +334,19 @@ g_sigusr2_raised = true; } -void SigUsr1Handler(int, siginfo_t*, void*) { +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS void SigUsr1Handler(int, siginfo_t*, void*) { raise(SIGUSR2); ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } -ABSL_ATTRIBUTE_NOINLINE void RaiseSignal() { +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NOINLINE void RaiseSignal() { g_return_address = __builtin_return_address(0); raise(SIGUSR1); ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } -ABSL_ATTRIBUTE_NOINLINE void TestNestedSignal() { +ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NOINLINE void +TestNestedSignal() { constexpr size_t kAltstackSize = 1 << 14; // Allocate altstack on regular stack to make sure it'll have a higher // address than some of the regular stack frames.
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h index 1272168..7855a10 100644 --- a/absl/flags/internal/flag.h +++ b/absl/flags/internal/flag.h
@@ -304,13 +304,11 @@ template <typename T> using FlagUseOneWordStorage = - std::integral_constant<bool, - std::is_trivially_copyable_v<T> && (sizeof(T) <= 8)>; + std::bool_constant<std::is_trivially_copyable_v<T> && (sizeof(T) <= 8)>; template <class T> using FlagUseSequenceLockStorage = - std::integral_constant<bool, - std::is_trivially_copyable_v<T> && (sizeof(T) > 8)>; + std::bool_constant<std::is_trivially_copyable_v<T> && (sizeof(T) > 8)>; enum class FlagValueStorageKind : uint8_t { kValueAndInitBit = 0,
diff --git a/absl/flags/internal/sequence_lock_test.cc b/absl/flags/internal/sequence_lock_test.cc index c3ec372..a244d67 100644 --- a/absl/flags/internal/sequence_lock_test.cc +++ b/absl/flags/internal/sequence_lock_test.cc
@@ -113,12 +113,12 @@ return result; } -#ifndef ABSL_HAVE_THREAD_SANITIZER -const int kMaxThreads = absl::base_internal::NumCPUs(); -#else +#if defined(ABSL_HAVE_THREAD_SANITIZER) // With TSAN, a lot of threads contending for atomic access on the sequence // lock make this test run too slowly. const int kMaxThreads = std::min(absl::base_internal::NumCPUs(), 4); +#else +const int kMaxThreads = absl::base_internal::NumCPUs(); #endif // Return all of the interesting buffer sizes worth testing:
diff --git a/absl/flags/reflection.cc b/absl/flags/reflection.cc index fb64a65..e92ff96 100644 --- a/absl/flags/reflection.cc +++ b/absl/flags/reflection.cc
@@ -294,8 +294,8 @@ } // namespace void Retire(const char* name, FlagFastTypeId type_id, unsigned char* buf) { - static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize, ""); - static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, ""); + static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize); + static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment); auto* flag = ::new (buf) flags_internal::RetiredFlagObj(name, type_id); FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr); }
diff --git a/absl/functional/any_invocable_test.h b/absl/functional/any_invocable_test.h index 643f14f..d667fa4 100644 --- a/absl/functional/any_invocable_test.h +++ b/absl/functional/any_invocable_test.h
@@ -59,15 +59,14 @@ // This will cause a recursive trait instantiation if the SFINAE checks are // not ordered correctly for constructibility. static_assert(std::is_constructible_v<Wrapper<absl::AnyInvocable<void()>>, - Wrapper<absl::AnyInvocable<void()>>>, - ""); + Wrapper<absl::AnyInvocable<void()>>>); // A metafunction that takes the cv and l-value reference qualifiers that were // associated with a function type (here passed via qualifiers of an object // type), and . template <class Qualifiers, class This> struct QualifiersForThisImpl { - static_assert(std::is_object_v<This>, ""); + static_assert(std::is_object_v<This>); using type = std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&; }; @@ -78,7 +77,7 @@ template <class Qualifiers, class This> struct QualifiersForThisImpl<Qualifiers&&, This> { - static_assert(std::is_object_v<This>, ""); + static_assert(std::is_object_v<This>); using type = std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&&; }; @@ -1011,7 +1010,7 @@ EXPECT_FALSE(static_cast<bool>(other)); EXPECT_TRUE( - absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value); + std::is_nothrow_swappable_v<AnyInvType>); } // Member swap @@ -1046,7 +1045,7 @@ EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value); EXPECT_TRUE( - absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value); + std::is_nothrow_swappable_v<AnyInvType>); } // Member swap @@ -1083,7 +1082,7 @@ EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value); EXPECT_TRUE( - absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value); + std::is_nothrow_swappable_v<AnyInvType>); } // Member swap @@ -1121,7 +1120,7 @@ EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value); EXPECT_TRUE( - absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value); + std::is_nothrow_swappable_v<AnyInvType>); } // Member swap @@ -1280,8 +1279,8 @@ Result(Result&&) = delete; }; - static_assert(!std::is_move_constructible_v<Result>, ""); - static_assert(!std::is_copy_constructible_v<Result>, ""); + static_assert(!std::is_move_constructible_v<Result>); + static_assert(!std::is_copy_constructible_v<Result>); // Assumption check: it should nevertheless be possible to use functors that // return a Result struct according to the language rules. @@ -1358,8 +1357,8 @@ Result(Result&&) = delete; }; - static_assert(!std::is_move_constructible_v<Result>, ""); - static_assert(!std::is_copy_constructible_v<Result>, ""); + static_assert(!std::is_move_constructible_v<Result>); + static_assert(!std::is_copy_constructible_v<Result>); // Assumption check: it should nevertheless be possible to use functors that // return a Result struct according to the language rules. @@ -1590,9 +1589,8 @@ // Minimal SFINAE testing for platforms where we can't run the tests, but we can // build binaries for. -static_assert(std::is_convertible_v<void (*)(), absl::AnyInvocable<void() &&>>, - ""); -static_assert(!std::is_convertible_v<void*, absl::AnyInvocable<void() &&>>, ""); +static_assert(std::is_convertible_v<void (*)(), absl::AnyInvocable<void() &&>>); +static_assert(!std::is_convertible_v<void*, absl::AnyInvocable<void() &&>>); } // namespace absl_any_invocable_test
diff --git a/absl/functional/bind_back.h b/absl/functional/bind_back.h index ba31fb4..8d9ff7c 100644 --- a/absl/functional/bind_back.h +++ b/absl/functional/bind_back.h
@@ -30,11 +30,9 @@ #ifndef ABSL_FUNCTIONAL_BIND_BACK_H_ #define ABSL_FUNCTIONAL_BIND_BACK_H_ -#ifdef __has_include #if __has_include(<version>) #include <version> #endif -#endif #if defined(__cpp_lib_bind_back) && __cpp_lib_bind_back >= 202202L #include <functional> // For std::bind_back.
diff --git a/absl/functional/bind_front.h b/absl/functional/bind_front.h index 09adc09..4dcee39 100644 --- a/absl/functional/bind_front.h +++ b/absl/functional/bind_front.h
@@ -30,11 +30,9 @@ #ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_ #define ABSL_FUNCTIONAL_BIND_FRONT_H_ -#ifdef __has_include #if __has_include(<version>) #include <version> #endif -#endif #if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L #include <functional> // For std::bind_front.
diff --git a/absl/functional/internal/any_invocable.h b/absl/functional/internal/any_invocable.h index 4698442..1ff8bb6 100644 --- a/absl/functional/internal/any_invocable.h +++ b/absl/functional/internal/any_invocable.h
@@ -63,7 +63,6 @@ #include <type_traits> #include <utility> -#include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/macros.h" #include "absl/base/nullability.h" @@ -252,7 +251,7 @@ case FunctionToCall::relocate_from_to_and_query_rust: // NOTE: Requires that the left-hand operand is already empty. ::new (static_cast<void*>(&to->storage)) T(std::move(from_object)); - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case FunctionToCall::dispose: from_object.~T(); // Must not throw. // NOLINT return;
diff --git a/absl/hash/hash_benchmark.cc b/absl/hash/hash_benchmark.cc index 86650b3..a6b0e81 100644 --- a/absl/hash/hash_benchmark.cc +++ b/absl/hash/hash_benchmark.cc
@@ -196,7 +196,7 @@ auto t6 = std::tuple_cat(t5, t5); // Ideally this would be much larger, but some configurations can't handle // making tuples with that many elements. They break inside std::tuple itself. - static_assert(std::tuple_size<decltype(t6)>::value == 32, ""); + static_assert(std::tuple_size<decltype(t6)>::value == 32); return t6; } @@ -344,7 +344,7 @@ static char entropy[kEntropySize + 1024]; ABSL_ATTRIBUTE_UNUSED static const bool kInitialized = [] { absl::BitGen gen; - static_assert(sizeof(entropy) % sizeof(uint64_t) == 0, ""); + static_assert(sizeof(entropy) % sizeof(uint64_t) == 0); for (int i = 0; i != sizeof(entropy); i += sizeof(uint64_t)) { auto rand = absl::Uniform<uint64_t>(gen); memcpy(&entropy[i], &rand, sizeof(uint64_t)); @@ -365,8 +365,8 @@ template <class T> struct PodRand { - static_assert(std::is_pod_v<T>, ""); - static_assert(kEntropySize + sizeof(T) < sizeof(entropy), ""); + static_assert(std::is_pod_v<T>); + static_assert(kEntropySize + sizeof(T) < sizeof(entropy)); T Get(size_t i) const { T v; @@ -377,7 +377,7 @@ template <size_t N> struct StringRand { - static_assert(kEntropySize + N < sizeof(entropy), ""); + static_assert(kEntropySize + N < sizeof(entropy)); absl::string_view Get(size_t i) const { // This has a small bias towards small numbers. Because max N is ~200 this
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc index d20b296..c8d8235 100644 --- a/absl/hash/hash_test.cc +++ b/absl/hash/hash_test.cc
@@ -923,7 +923,7 @@ typename H, InvokeTag... Tags, typename = typename EnableIfContained<InvokeTag::kHashValue, Tags...>::type> H AbslHashValue(H state, CustomHashType<Tags...> t) { - static_assert(MinTag<Tags...>::value == InvokeTag::kHashValue, ""); + static_assert(MinTag<Tags...>::value == InvokeTag::kHashValue); return H::combine(std::move(state), t.value + static_cast<int>(InvokeTag::kHashValue)); } @@ -949,7 +949,7 @@ template <InvokeTag... TagsIn, typename = typename EnableIfContained< InvokeTag::kLegacyHash, TagsIn...>::type> size_t operator()(CustomHashType<TagsIn...> t) const { - static_assert(MinTag<Tags...>::value == InvokeTag::kLegacyHash, ""); + static_assert(MinTag<Tags...>::value == InvokeTag::kLegacyHash); return t.value + static_cast<int>(InvokeTag::kLegacyHash); } }; @@ -962,7 +962,7 @@ template <InvokeTag... TagsIn, typename = typename EnableIfContained< InvokeTag::kStdHash, TagsIn...>::type> size_t operator()(CustomHashType<TagsIn...> t) const { - static_assert(MinTag<Tags...>::value == InvokeTag::kStdHash, ""); + static_assert(MinTag<Tags...>::value == InvokeTag::kStdHash); return t.value + static_cast<int>(InvokeTag::kStdHash); } }; @@ -1041,10 +1041,10 @@ static_assert(sizeof(StructWithPadding) > sizeof(char) + sizeof(int), "StructWithPadding doesn't have padding"); -static_assert(std::is_standard_layout_v<StructWithPadding>, ""); +static_assert(std::is_standard_layout_v<StructWithPadding>); // This check has to be disabled because libstdc++ doesn't support it. -// static_assert(std::is_trivially_constructible_v<StructWithPadding>, ""); +// static_assert(std::is_trivially_constructible_v<StructWithPadding>); template <typename T> struct ArraySlice {
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 9463746..b17c574 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h
@@ -31,11 +31,9 @@ // GCC15 warns that <ciso646> is deprecated in C++17 and suggests using // <version> instead, even though <version> is not available in C++17 mode prior // to GCC9. -#if defined(__has_include) #if __has_include(<version>) #define ABSL_INTERNAL_VERSION_HEADER_AVAILABLE 1 #endif -#endif // For feature testing and determining which headers can be included. #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L || \ @@ -575,9 +573,7 @@ #else // On other platforms, we assume that pointers-to-members do not have // padding. -#ifdef __cpp_lib_has_unique_object_representations static_assert(std::has_unique_object_representations_v<T C::*>); -#endif // __cpp_lib_has_unique_object_representations return n; #endif };
diff --git a/absl/hash/internal/spy_hash_state.h b/absl/hash/internal/spy_hash_state.h index 51caaf1..9217ec1 100644 --- a/absl/hash/internal/spy_hash_state.h +++ b/absl/hash/internal/spy_hash_state.h
@@ -48,7 +48,7 @@ class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> { public: SpyHashStateImpl() : error_(std::make_shared<std::optional<std::string>>()) { - static_assert(std::is_void_v<T>, ""); + static_assert(std::is_void_v<T>); } // Move-only
diff --git a/absl/log/internal/log_format.cc b/absl/log/internal/log_format.cc index d54cf19..c7bb3ec 100644 --- a/absl/log/internal/log_format.cc +++ b/absl/log/internal/log_format.cc
@@ -47,29 +47,25 @@ namespace log_internal { namespace { -// This templated function avoids compiler warnings about tautological -// comparisons when log_internal::Tid is unsigned. It can be replaced with a -// constexpr if once the minimum C++ version Abseil supports is C++17. +// The `if constexpr` avoids compiler warnings about tautological comparisons +// when log_internal::Tid is unsigned. template <typename T> -inline std::enable_if_t<!std::is_signed_v<T>> PutLeadingWhitespace(T tid, - char*& p) { - if (tid < 10) *p++ = ' '; - if (tid < 100) *p++ = ' '; - if (tid < 1000) *p++ = ' '; - if (tid < 10000) *p++ = ' '; - if (tid < 100000) *p++ = ' '; - if (tid < 1000000) *p++ = ' '; -} - -template <typename T> -inline std::enable_if_t<std::is_signed_v<T>> PutLeadingWhitespace(T tid, - char*& p) { - if (tid >= 0 && tid < 10) *p++ = ' '; - if (tid > -10 && tid < 100) *p++ = ' '; - if (tid > -100 && tid < 1000) *p++ = ' '; - if (tid > -1000 && tid < 10000) *p++ = ' '; - if (tid > -10000 && tid < 100000) *p++ = ' '; - if (tid > -100000 && tid < 1000000) *p++ = ' '; +inline void PutLeadingWhitespace(T tid, char*& p) { + if constexpr (std::is_signed_v<T>) { + if (tid >= 0 && tid < 10) *p++ = ' '; + if (tid > -10 && tid < 100) *p++ = ' '; + if (tid > -100 && tid < 1000) *p++ = ' '; + if (tid > -1000 && tid < 10000) *p++ = ' '; + if (tid > -10000 && tid < 100000) *p++ = ' '; + if (tid > -100000 && tid < 1000000) *p++ = ' '; + } else { + if (tid < 10) *p++ = ' '; + if (tid < 100) *p++ = ' '; + if (tid < 1000) *p++ = ' '; + if (tid < 10000) *p++ = ' '; + if (tid < 100000) *p++ = ' '; + if (tid < 1000000) *p++ = ' '; + } } // The fields before the filename are all fixed-width except for the thread ID,
diff --git a/absl/log/internal/vlog_config_benchmark.cc b/absl/log/internal/vlog_config_benchmark.cc index 2634ca3..1916e2c 100644 --- a/absl/log/internal/vlog_config_benchmark.cc +++ b/absl/log/internal/vlog_config_benchmark.cc
@@ -115,7 +115,7 @@ sites[num_tus - 1]->next_.store(nullptr, std::memory_order_seq_cst); } ~SyntheticBinary() { - static_assert(std::is_trivially_destructible_v<VLogSite>, ""); + static_assert(std::is_trivially_destructible_v<VLogSite>); absl::log_internal::SetVModuleListHeadForTestOnly(nullptr); }
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 6ca2dc8..11701e2 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h
@@ -17,7 +17,7 @@ // type_traits.h // ----------------------------------------------------------------------------- // -// This file contains C++11-compatible versions of standard <type_traits> API +// This file contains C++17-compatible versions of standard <type_traits> API // functions for determining the characteristics of types. Such traits can // support type inference, classification, and transformation, as well as // make it easier to write templates based on generic type behavior. @@ -54,13 +54,9 @@ #include <span> // NOLINT(build/c++20) #endif -// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17 -// feature. -#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) +// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is +// predefined by every C++17 implementation. #define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__ -#else // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) -#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT alignof(std::max_align_t) -#endif // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__) namespace absl { ABSL_NAMESPACE_BEGIN @@ -241,7 +237,7 @@ #else // remove_cvref() // -// C++11 compatible implementation of std::remove_cvref which was added in +// C++17 compatible implementation of std::remove_cvref which was added in // C++20. template <typename T> struct remove_cvref { @@ -276,22 +272,16 @@ namespace type_traits_internal { -#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \ - (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -// std::result_of is deprecated (C++17) or removed (C++20) template <typename> struct result_of; template <typename F, typename... Args> struct result_of<F(Args...)> : std::invoke_result<F, Args...> {}; -#else -template <typename F> -using result_of = std::result_of<F>; -#endif } // namespace type_traits_internal template <typename F> -using result_of_t = typename type_traits_internal::result_of<F>::type; +using result_of_t [[deprecated("Use std::invoke_result_t instead.")]] = + typename type_traits_internal::result_of<F>::type; namespace type_traits_internal { @@ -347,68 +337,12 @@ Helper::Sink(Helper::DoIt<Ts>()...); } -} // namespace type_traits_internal - -// An internal namespace that is required to implement the C++17 swap traits. -// It is not further nested in type_traits_internal to avoid long symbol names. -namespace swap_internal { - -// Necessary for the traits. -using std::swap; - -// This declaration prevents global `swap` and `absl::swap` overloads from being -// considered unless ADL picks them up. -void swap(); +template <class T> +using IsSwappable ABSL_DEPRECATE_AND_INLINE() = std::is_swappable<T>; template <class T> -using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>())); - -// NOTE: This dance with the default template parameter is for MSVC. -template <class T, class IsNoexcept = std::bool_constant<noexcept( - swap(std::declval<T&>(), std::declval<T&>()))>> -using IsNothrowSwappableImpl = std::enable_if_t<IsNoexcept::value>; - -// IsSwappable -// -// Determines whether the standard swap idiom is a valid expression for -// arguments of type `T`. -template <class T> -struct IsSwappable - : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {}; - -// IsNothrowSwappable -// -// Determines whether the standard swap idiom is a valid expression for -// arguments of type `T` and is noexcept. -template <class T> -struct IsNothrowSwappable - : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {}; - -// Swap() -// -// Performs the swap idiom from a namespace where valid candidates may only be -// found in `std` or via ADL. -template <class T, std::enable_if_t<IsSwappable<T>::value, int> = 0> -void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) { - swap(lhs, rhs); -} - -// StdSwapIsUnconstrained -// -// Some standard library implementations are broken in that they do not -// constrain `std::swap`. This will effectively tell us if we are dealing with -// one of those implementations. -using StdSwapIsUnconstrained = IsSwappable<void()>; - -} // namespace swap_internal - -namespace type_traits_internal { - -// Make the swap-related traits/function accessible from this namespace. -using swap_internal::IsNothrowSwappable; -using swap_internal::IsSwappable; -using swap_internal::StdSwapIsUnconstrained; -using swap_internal::Swap; +using IsNothrowSwappable ABSL_DEPRECATE_AND_INLINE() = + std::is_nothrow_swappable<T>; } // namespace type_traits_internal @@ -484,10 +418,9 @@ // TODO(b/325479096): Remove this case. template <class T> struct is_trivially_relocatable - : std::integral_constant<bool, - std::is_trivially_copyable_v<T> || - (__is_trivially_relocatable(T) && - std::is_trivially_move_assignable_v<T>)> {}; + : std::bool_constant<std::is_trivially_copyable_v<T> || + (__is_trivially_relocatable(T) && + std::is_trivially_move_assignable_v<T>)> {}; #else // Otherwise we use a fallback that detects only those types we can feasibly // detect. Any type that is trivially copyable is by definition trivially
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index 3675a0f..a11049c 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc
@@ -184,7 +184,7 @@ struct GetTypeExtT { template <typename T> - absl::result_of_t<const GetTypeT&(T)> operator()(T&& arg) const { + std::invoke_result_t<const GetTypeT&, T> operator()(T&& arg) const { return GetType(std::forward<T>(arg)); } @@ -216,7 +216,6 @@ TEST(TypeTraitsTest, IsSwappable) { using absl::type_traits_internal::IsSwappable; - using absl::type_traits_internal::StdSwapIsUnconstrained; EXPECT_TRUE(IsSwappable<int>::value); @@ -229,14 +228,14 @@ ~NoConstruct() = default; }; - EXPECT_EQ(IsSwappable<NoConstruct>::value, StdSwapIsUnconstrained::value); + EXPECT_FALSE(IsSwappable<NoConstruct>::value); struct NoAssign { NoAssign(NoAssign&&) {} NoAssign& operator=(NoAssign&&) = delete; ~NoAssign() = default; }; - EXPECT_EQ(IsSwappable<NoAssign>::value, StdSwapIsUnconstrained::value); + EXPECT_FALSE(IsSwappable<NoAssign>::value); EXPECT_FALSE(IsSwappable<adl_namespace::DeletedSwap>::value); @@ -245,7 +244,6 @@ TEST(TypeTraitsTest, IsNothrowSwappable) { using absl::type_traits_internal::IsNothrowSwappable; - using absl::type_traits_internal::StdSwapIsUnconstrained; EXPECT_TRUE(IsNothrowSwappable<int>::value); @@ -279,9 +277,9 @@ } TEST(TriviallyRelocatable, PrimitiveTypes) { - static_assert(absl::is_trivially_relocatable<int>::value, ""); - static_assert(absl::is_trivially_relocatable<char>::value, ""); - static_assert(absl::is_trivially_relocatable<void*>::value, ""); + static_assert(absl::is_trivially_relocatable<int>::value); + static_assert(absl::is_trivially_relocatable<char>::value); + static_assert(absl::is_trivially_relocatable<void*>::value); } // User-defined types can be trivially relocatable as long as they don't have a @@ -292,7 +290,7 @@ int y; }; - static_assert(absl::is_trivially_relocatable<S>::value, ""); + static_assert(absl::is_trivially_relocatable<S>::value); } // A user-provided move constructor disqualifies a type from being trivially @@ -302,7 +300,7 @@ S(S&&) {} // NOLINT(modernize-use-equals-default) }; - static_assert(!absl::is_trivially_relocatable<S>::value, ""); + static_assert(!absl::is_trivially_relocatable<S>::value); } // A user-provided copy constructor disqualifies a type from being trivially @@ -312,7 +310,7 @@ S(const S&) {} // NOLINT(modernize-use-equals-default) }; - static_assert(!absl::is_trivially_relocatable<S>::value, ""); + static_assert(!absl::is_trivially_relocatable<S>::value); } // A user-provided copy assignment operator disqualifies a type from @@ -325,7 +323,7 @@ } }; - static_assert(!absl::is_trivially_relocatable<S>::value, ""); + static_assert(!absl::is_trivially_relocatable<S>::value); } // A user-provided move assignment operator disqualifies a type from @@ -336,7 +334,7 @@ S& operator=(S&&) { return *this; } // NOLINT(modernize-use-equals-default) }; - static_assert(!absl::is_trivially_relocatable<S>::value, ""); + static_assert(!absl::is_trivially_relocatable<S>::value); } // A user-provided destructor disqualifies a type from being trivially @@ -346,7 +344,7 @@ ~S() {} // NOLINT(modernize-use-equals-default) }; - static_assert(!absl::is_trivially_relocatable<S>::value, ""); + static_assert(!absl::is_trivially_relocatable<S>::value); } TEST(Ownership, References) {
diff --git a/absl/numeric/bits_test.cc b/absl/numeric/bits_test.cc index e2c6409..8cf2378 100644 --- a/absl/numeric/bits_test.cc +++ b/absl/numeric/bits_test.cc
@@ -62,32 +62,32 @@ EXPECT_EQ(rotl(UIntType{0x12}, 0), uint8_t{0x12}); EXPECT_EQ(rotr(UIntType{0x12}, -4), uint8_t{0x21}); - static_assert(rotl(UIntType{0x12}, 0) == uint8_t{0x12}, ""); + static_assert(rotl(UIntType{0x12}, 0) == uint8_t{0x12}); - static_assert(rotr(UIntType{0x12}, 0) == uint8_t{0x12}, ""); + static_assert(rotr(UIntType{0x12}, 0) == uint8_t{0x12}); EXPECT_EQ(rotr(UIntType{0x12}, 0), uint8_t{0x12}); #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ - static_assert(countl_zero(UIntType{}) == 8, ""); - static_assert(countl_zero(static_cast<UIntType>(-1)) == 0, ""); + static_assert(countl_zero(UIntType{}) == 8); + static_assert(countl_zero(static_cast<UIntType>(-1)) == 0); - static_assert(countl_one(UIntType{}) == 0, ""); - static_assert(countl_one(static_cast<UIntType>(-1)) == 8, ""); + static_assert(countl_one(UIntType{}) == 0); + static_assert(countl_one(static_cast<UIntType>(-1)) == 8); - static_assert(countr_zero(UIntType{}) == 8, ""); - static_assert(countr_zero(static_cast<UIntType>(-1)) == 0, ""); + static_assert(countr_zero(UIntType{}) == 8); + static_assert(countr_zero(static_cast<UIntType>(-1)) == 0); - static_assert(countr_one(UIntType{}) == 0, ""); - static_assert(countr_one(static_cast<UIntType>(-1)) == 8, ""); + static_assert(countr_one(UIntType{}) == 0); + static_assert(countr_one(static_cast<UIntType>(-1)) == 8); - static_assert(popcount(UIntType{}) == 0, ""); - static_assert(popcount(UIntType{1}) == 1, ""); - static_assert(popcount(static_cast<UIntType>(-1)) == 8, ""); + static_assert(popcount(UIntType{}) == 0); + static_assert(popcount(UIntType{1}) == 1); + static_assert(popcount(static_cast<UIntType>(-1)) == 8); - static_assert(bit_width(UIntType{}) == 0, ""); - static_assert(bit_width(UIntType{1}) == 1, ""); - static_assert(bit_width(UIntType{3}) == 2, ""); - static_assert(bit_width(static_cast<UIntType>(-1)) == 8, ""); + static_assert(bit_width(UIntType{}) == 0); + static_assert(bit_width(UIntType{1}) == 1); + static_assert(bit_width(UIntType{3}) == 2); + static_assert(bit_width(static_cast<UIntType>(-1)) == 8); #endif EXPECT_EQ(countl_zero(UIntType{}), 8); @@ -115,12 +115,11 @@ } TEST(Rotate, Left) { - static_assert(rotl(uint8_t{0x12}, 0) == uint8_t{0x12}, ""); - static_assert(rotl(uint16_t{0x1234}, 0) == uint16_t{0x1234}, ""); - static_assert(rotl(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}, ""); + static_assert(rotl(uint8_t{0x12}, 0) == uint8_t{0x12}); + static_assert(rotl(uint16_t{0x1234}, 0) == uint16_t{0x1234}); + static_assert(rotl(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}); static_assert(rotl(uint64_t{0x12345678ABCDEF01ULL}, 0) == - uint64_t{0x12345678ABCDEF01ULL}, - ""); + uint64_t{0x12345678ABCDEF01ULL}); EXPECT_EQ(rotl(uint8_t{0x12}, 0), uint8_t{0x12}); EXPECT_EQ(rotl(uint16_t{0x1234}, 0), uint16_t{0x1234}); @@ -157,12 +156,11 @@ } TEST(Rotate, Right) { - static_assert(rotr(uint8_t{0x12}, 0) == uint8_t{0x12}, ""); - static_assert(rotr(uint16_t{0x1234}, 0) == uint16_t{0x1234}, ""); - static_assert(rotr(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}, ""); + static_assert(rotr(uint8_t{0x12}, 0) == uint8_t{0x12}); + static_assert(rotr(uint16_t{0x1234}, 0) == uint16_t{0x1234}); + static_assert(rotr(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}); static_assert(rotr(uint64_t{0x12345678ABCDEF01ULL}, 0) == - uint64_t{0x12345678ABCDEF01ULL}, - ""); + uint64_t{0x12345678ABCDEF01ULL}); EXPECT_EQ(rotr(uint8_t{0x12}, 0), uint8_t{0x12}); EXPECT_EQ(rotr(uint16_t{0x1234}, 0), uint16_t{0x1234}); @@ -242,14 +240,14 @@ TEST(Counting, LeadingZeroes) { #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ - static_assert(countl_zero(uint8_t{}) == 8, ""); - static_assert(countl_zero(static_cast<uint8_t>(-1)) == 0, ""); - static_assert(countl_zero(uint16_t{}) == 16, ""); - static_assert(countl_zero(static_cast<uint16_t>(-1)) == 0, ""); - static_assert(countl_zero(uint32_t{}) == 32, ""); - static_assert(countl_zero(~uint32_t{}) == 0, ""); - static_assert(countl_zero(uint64_t{}) == 64, ""); - static_assert(countl_zero(~uint64_t{}) == 0, ""); + static_assert(countl_zero(uint8_t{}) == 8); + static_assert(countl_zero(static_cast<uint8_t>(-1)) == 0); + static_assert(countl_zero(uint16_t{}) == 16); + static_assert(countl_zero(static_cast<uint16_t>(-1)) == 0); + static_assert(countl_zero(uint32_t{}) == 32); + static_assert(countl_zero(~uint32_t{}) == 0); + static_assert(countl_zero(uint64_t{}) == 64); + static_assert(countl_zero(~uint64_t{}) == 0); #endif EXPECT_EQ(countl_zero(uint8_t{}), 8); @@ -280,14 +278,14 @@ TEST(Counting, LeadingOnes) { #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ - static_assert(countl_one(uint8_t{}) == 0, ""); - static_assert(countl_one(static_cast<uint8_t>(-1)) == 8, ""); - static_assert(countl_one(uint16_t{}) == 0, ""); - static_assert(countl_one(static_cast<uint16_t>(-1)) == 16, ""); - static_assert(countl_one(uint32_t{}) == 0, ""); - static_assert(countl_one(~uint32_t{}) == 32, ""); - static_assert(countl_one(uint64_t{}) == 0, ""); - static_assert(countl_one(~uint64_t{}) == 64, ""); + static_assert(countl_one(uint8_t{}) == 0); + static_assert(countl_one(static_cast<uint8_t>(-1)) == 8); + static_assert(countl_one(uint16_t{}) == 0); + static_assert(countl_one(static_cast<uint16_t>(-1)) == 16); + static_assert(countl_one(uint32_t{}) == 0); + static_assert(countl_one(~uint32_t{}) == 32); + static_assert(countl_one(uint64_t{}) == 0); + static_assert(countl_one(~uint64_t{}) == 64); #endif EXPECT_EQ(countl_one(uint8_t{}), 0); @@ -302,14 +300,14 @@ TEST(Counting, TrailingZeroes) { #if ABSL_INTERNAL_HAS_CONSTEXPR_CTZ - static_assert(countr_zero(uint8_t{}) == 8, ""); - static_assert(countr_zero(static_cast<uint8_t>(-1)) == 0, ""); - static_assert(countr_zero(uint16_t{}) == 16, ""); - static_assert(countr_zero(static_cast<uint16_t>(-1)) == 0, ""); - static_assert(countr_zero(uint32_t{}) == 32, ""); - static_assert(countr_zero(~uint32_t{}) == 0, ""); - static_assert(countr_zero(uint64_t{}) == 64, ""); - static_assert(countr_zero(~uint64_t{}) == 0, ""); + static_assert(countr_zero(uint8_t{}) == 8); + static_assert(countr_zero(static_cast<uint8_t>(-1)) == 0); + static_assert(countr_zero(uint16_t{}) == 16); + static_assert(countr_zero(static_cast<uint16_t>(-1)) == 0); + static_assert(countr_zero(uint32_t{}) == 32); + static_assert(countr_zero(~uint32_t{}) == 0); + static_assert(countr_zero(uint64_t{}) == 64); + static_assert(countr_zero(~uint64_t{}) == 0); #endif EXPECT_EQ(countr_zero(uint8_t{}), 8); @@ -324,14 +322,14 @@ TEST(Counting, TrailingOnes) { #if ABSL_INTERNAL_HAS_CONSTEXPR_CTZ - static_assert(countr_one(uint8_t{}) == 0, ""); - static_assert(countr_one(static_cast<uint8_t>(-1)) == 8, ""); - static_assert(countr_one(uint16_t{}) == 0, ""); - static_assert(countr_one(static_cast<uint16_t>(-1)) == 16, ""); - static_assert(countr_one(uint32_t{}) == 0, ""); - static_assert(countr_one(~uint32_t{}) == 32, ""); - static_assert(countr_one(uint64_t{}) == 0, ""); - static_assert(countr_one(~uint64_t{}) == 64, ""); + static_assert(countr_one(uint8_t{}) == 0); + static_assert(countr_one(static_cast<uint8_t>(-1)) == 8); + static_assert(countr_one(uint16_t{}) == 0); + static_assert(countr_one(static_cast<uint16_t>(-1)) == 16); + static_assert(countr_one(uint32_t{}) == 0); + static_assert(countr_one(~uint32_t{}) == 32); + static_assert(countr_one(uint64_t{}) == 0); + static_assert(countr_one(~uint64_t{}) == 64); #endif EXPECT_EQ(countr_one(uint8_t{}), 0); @@ -346,18 +344,18 @@ TEST(Counting, Popcount) { #if ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT - static_assert(popcount(uint8_t{}) == 0, ""); - static_assert(popcount(uint8_t{1}) == 1, ""); - static_assert(popcount(static_cast<uint8_t>(-1)) == 8, ""); - static_assert(popcount(uint16_t{}) == 0, ""); - static_assert(popcount(uint16_t{1}) == 1, ""); - static_assert(popcount(static_cast<uint16_t>(-1)) == 16, ""); - static_assert(popcount(uint32_t{}) == 0, ""); - static_assert(popcount(uint32_t{1}) == 1, ""); - static_assert(popcount(~uint32_t{}) == 32, ""); - static_assert(popcount(uint64_t{}) == 0, ""); - static_assert(popcount(uint64_t{1}) == 1, ""); - static_assert(popcount(~uint64_t{}) == 64, ""); + static_assert(popcount(uint8_t{}) == 0); + static_assert(popcount(uint8_t{1}) == 1); + static_assert(popcount(static_cast<uint8_t>(-1)) == 8); + static_assert(popcount(uint16_t{}) == 0); + static_assert(popcount(uint16_t{1}) == 1); + static_assert(popcount(static_cast<uint16_t>(-1)) == 16); + static_assert(popcount(uint32_t{}) == 0); + static_assert(popcount(uint32_t{1}) == 1); + static_assert(popcount(~uint32_t{}) == 32); + static_assert(popcount(uint64_t{}) == 0); + static_assert(popcount(uint64_t{1}) == 1); + static_assert(popcount(~uint64_t{}) == 64); #endif // ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT EXPECT_EQ(popcount(uint8_t{}), 0); @@ -452,15 +450,15 @@ EXPECT_FALSE(has_single_bit(uint64_t{})); EXPECT_FALSE(has_single_bit(~uint64_t{})); - static_assert(!has_single_bit(0u), ""); - static_assert(has_single_bit(1u), ""); - static_assert(has_single_bit(2u), ""); - static_assert(!has_single_bit(3u), ""); - static_assert(has_single_bit(4u), ""); - static_assert(!has_single_bit(1337u), ""); - static_assert(has_single_bit(65536u), ""); - static_assert(has_single_bit(uint32_t{1} << 30), ""); - static_assert(has_single_bit(uint64_t{1} << 42), ""); + static_assert(!has_single_bit(0u)); + static_assert(has_single_bit(1u)); + static_assert(has_single_bit(2u)); + static_assert(!has_single_bit(3u)); + static_assert(has_single_bit(4u)); + static_assert(!has_single_bit(1337u)); + static_assert(has_single_bit(65536u)); + static_assert(has_single_bit(uint32_t{1} << 30)); + static_assert(has_single_bit(uint64_t{1} << 42)); EXPECT_FALSE(has_single_bit(0u)); EXPECT_TRUE(has_single_bit(1u)); @@ -493,20 +491,18 @@ TEST(IntegralPowersOfTwo, Ceiling) { #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ - static_assert(bit_ceil(0u) == 1, ""); - static_assert(bit_ceil(1u) == 1, ""); - static_assert(bit_ceil(2u) == 2, ""); - static_assert(bit_ceil(3u) == 4, ""); - static_assert(bit_ceil(4u) == 4, ""); - static_assert(bit_ceil(1337u) == 2048, ""); - static_assert(bit_ceil(65536u) == 65536, ""); - static_assert(bit_ceil(65536u - 1337u) == 65536, ""); - static_assert(bit_ceil(uint32_t{0x80000000}) == uint32_t{0x80000000}, ""); - static_assert(bit_ceil(uint64_t{0x40000000000}) == uint64_t{0x40000000000}, - ""); - static_assert( - bit_ceil(uint64_t{0x8000000000000000}) == uint64_t{0x8000000000000000}, - ""); + static_assert(bit_ceil(0u) == 1); + static_assert(bit_ceil(1u) == 1); + static_assert(bit_ceil(2u) == 2); + static_assert(bit_ceil(3u) == 4); + static_assert(bit_ceil(4u) == 4); + static_assert(bit_ceil(1337u) == 2048); + static_assert(bit_ceil(65536u) == 65536); + static_assert(bit_ceil(65536u - 1337u) == 65536); + static_assert(bit_ceil(uint32_t{0x80000000}) == uint32_t{0x80000000}); + static_assert(bit_ceil(uint64_t{0x40000000000}) == uint64_t{0x40000000000}); + static_assert(bit_ceil(uint64_t{0x8000000000000000}) == + uint64_t{0x8000000000000000}); EXPECT_TRUE((IsBitCeilConstantExpression<uint8_t, uint8_t{0x0}>(0))); EXPECT_TRUE((IsBitCeilConstantExpression<uint8_t, uint8_t{0x80}>(0))); @@ -547,16 +543,15 @@ TEST(IntegralPowersOfTwo, Floor) { #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ - static_assert(bit_floor(0u) == 0, ""); - static_assert(bit_floor(1u) == 1, ""); - static_assert(bit_floor(2u) == 2, ""); - static_assert(bit_floor(3u) == 2, ""); - static_assert(bit_floor(4u) == 4, ""); - static_assert(bit_floor(1337u) == 1024, ""); - static_assert(bit_floor(65536u) == 65536, ""); - static_assert(bit_floor(65536u - 1337u) == 32768, ""); - static_assert(bit_floor(uint64_t{0x40000000000}) == uint64_t{0x40000000000}, - ""); + static_assert(bit_floor(0u) == 0); + static_assert(bit_floor(1u) == 1); + static_assert(bit_floor(2u) == 2); + static_assert(bit_floor(3u) == 2); + static_assert(bit_floor(4u) == 4); + static_assert(bit_floor(1337u) == 1024); + static_assert(bit_floor(65536u) == 65536); + static_assert(bit_floor(65536u - 1337u) == 32768); + static_assert(bit_floor(uint64_t{0x40000000000}) == uint64_t{0x40000000000}); #endif EXPECT_EQ(bit_floor(0u), 0); @@ -604,22 +599,22 @@ TEST(IntegralPowersOfTwo, Width) { #if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ - static_assert(bit_width(uint8_t{}) == 0, ""); - static_assert(bit_width(uint8_t{1}) == 1, ""); - static_assert(bit_width(uint8_t{3}) == 2, ""); - static_assert(bit_width(static_cast<uint8_t>(-1)) == 8, ""); - static_assert(bit_width(uint16_t{}) == 0, ""); - static_assert(bit_width(uint16_t{1}) == 1, ""); - static_assert(bit_width(uint16_t{3}) == 2, ""); - static_assert(bit_width(static_cast<uint16_t>(-1)) == 16, ""); - static_assert(bit_width(uint32_t{}) == 0, ""); - static_assert(bit_width(uint32_t{1}) == 1, ""); - static_assert(bit_width(uint32_t{3}) == 2, ""); - static_assert(bit_width(~uint32_t{}) == 32, ""); - static_assert(bit_width(uint64_t{}) == 0, ""); - static_assert(bit_width(uint64_t{1}) == 1, ""); - static_assert(bit_width(uint64_t{3}) == 2, ""); - static_assert(bit_width(~uint64_t{}) == 64, ""); + static_assert(bit_width(uint8_t{}) == 0); + static_assert(bit_width(uint8_t{1}) == 1); + static_assert(bit_width(uint8_t{3}) == 2); + static_assert(bit_width(static_cast<uint8_t>(-1)) == 8); + static_assert(bit_width(uint16_t{}) == 0); + static_assert(bit_width(uint16_t{1}) == 1); + static_assert(bit_width(uint16_t{3}) == 2); + static_assert(bit_width(static_cast<uint16_t>(-1)) == 16); + static_assert(bit_width(uint32_t{}) == 0); + static_assert(bit_width(uint32_t{1}) == 1); + static_assert(bit_width(uint32_t{3}) == 2); + static_assert(bit_width(~uint32_t{}) == 32); + static_assert(bit_width(uint64_t{}) == 0); + static_assert(bit_width(uint64_t{1}) == 1); + static_assert(bit_width(uint64_t{3}) == 2); + static_assert(bit_width(~uint64_t{}) == 64); #endif EXPECT_EQ(bit_width(uint8_t{}), 0);
diff --git a/absl/numeric/int128.cc b/absl/numeric/int128.cc index 9987c15..5dfc5ea 100644 --- a/absl/numeric/int128.cc +++ b/absl/numeric/int128.cc
@@ -90,7 +90,7 @@ template <typename T> uint128 MakeUint128FromFloat(T v) { - static_assert(std::is_floating_point_v<T>, ""); + static_assert(std::is_floating_point_v<T>); // Rounding behavior is towards zero, same as for built-in types. @@ -114,8 +114,8 @@ // It is more work, so only use when we need the workaround. uint128 MakeUint128FromFloat(long double v) { // Go 50 bits at a time, that fits in a double - static_assert(std::numeric_limits<double>::digits >= 50, ""); - static_assert(std::numeric_limits<long double>::digits <= 150, ""); + static_assert(std::numeric_limits<double>::digits >= 50); + static_assert(std::numeric_limits<long double>::digits <= 150); // Undefined behavior if v is not finite or cannot fit into uint128. assert(std::isfinite(v) && v > -1 && v < std::ldexp(1.0L, 128));
diff --git a/absl/numeric/int128_test.cc b/absl/numeric/int128_test.cc index 35eacae..9c140f0 100644 --- a/absl/numeric/int128_test.cc +++ b/absl/numeric/int128_test.cc
@@ -93,10 +93,10 @@ #endif // ABSL_HAVE_INTRINSIC_INT128 TEST(Uint128, TrivialTraitsTest) { - static_assert(std::is_trivially_default_constructible_v<absl::uint128>, ""); - static_assert(std::is_trivially_copy_constructible_v<absl::uint128>, ""); - static_assert(std::is_trivially_copy_assignable_v<absl::uint128>, ""); - static_assert(std::is_trivially_destructible_v<absl::uint128>, ""); + static_assert(std::is_trivially_default_constructible_v<absl::uint128>); + static_assert(std::is_trivially_copy_constructible_v<absl::uint128>); + static_assert(std::is_trivially_copy_assignable_v<absl::uint128>); + static_assert(std::is_trivially_destructible_v<absl::uint128>); } TEST(Uint128, AllTests) { @@ -483,9 +483,9 @@ } TEST(Uint128, NumericLimitsTest) { - static_assert(std::numeric_limits<absl::uint128>::is_specialized, ""); - static_assert(!std::numeric_limits<absl::uint128>::is_signed, ""); - static_assert(std::numeric_limits<absl::uint128>::is_integer, ""); + static_assert(std::numeric_limits<absl::uint128>::is_specialized); + static_assert(!std::numeric_limits<absl::uint128>::is_signed); + static_assert(std::numeric_limits<absl::uint128>::is_integer); EXPECT_EQ(static_cast<int>(128 * std::log10(2)), std::numeric_limits<absl::uint128>::digits10); EXPECT_EQ(0, std::numeric_limits<absl::uint128>::min()); @@ -617,10 +617,10 @@ #endif // ABSL_HAVE_INTRINSIC_INT128 TEST(Int128, TrivialTraitsTest) { - static_assert(std::is_trivially_default_constructible_v<absl::int128>, ""); - static_assert(std::is_trivially_copy_constructible_v<absl::int128>, ""); - static_assert(std::is_trivially_copy_assignable_v<absl::int128>, ""); - static_assert(std::is_trivially_destructible_v<absl::int128>, ""); + static_assert(std::is_trivially_default_constructible_v<absl::int128>); + static_assert(std::is_trivially_copy_constructible_v<absl::int128>); + static_assert(std::is_trivially_copy_assignable_v<absl::int128>); + static_assert(std::is_trivially_destructible_v<absl::int128>); } TEST(Int128, BoolConversionTest) { @@ -1345,9 +1345,9 @@ } TEST(Int128, NumericLimitsTest) { - static_assert(std::numeric_limits<absl::int128>::is_specialized, ""); - static_assert(std::numeric_limits<absl::int128>::is_signed, ""); - static_assert(std::numeric_limits<absl::int128>::is_integer, ""); + static_assert(std::numeric_limits<absl::int128>::is_specialized); + static_assert(std::numeric_limits<absl::int128>::is_signed); + static_assert(std::numeric_limits<absl::int128>::is_integer); EXPECT_EQ(static_cast<int>(127 * std::log10(2)), std::numeric_limits<absl::int128>::digits10); EXPECT_EQ(absl::Int128Min(), std::numeric_limits<absl::int128>::min());
diff --git a/absl/random/beta_distribution.h b/absl/random/beta_distribution.h index 15311df..a2cdd25 100644 --- a/absl/random/beta_distribution.h +++ b/absl/random/beta_distribution.h
@@ -23,7 +23,6 @@ #include <ostream> #include <type_traits> -#include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/meta/type_traits.h" #include "absl/random/internal/fast_uniform_bits.h" @@ -387,7 +386,6 @@ case param_type::JOEHNK: return AlgorithmJoehnk(g, p); case param_type::CHENG_BA: - ABSL_FALLTHROUGH_INTENDED; case param_type::CHENG_BB: return AlgorithmCheng(g, p); default:
diff --git a/absl/random/distributions_test.cc b/absl/random/distributions_test.cc index 16c9e2e..9b081e9 100644 --- a/absl/random/distributions_test.cc +++ b/absl/random/distributions_test.cc
@@ -82,15 +82,13 @@ static_assert( std::conjunction_v< std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>, - std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>, - ""); + std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>); static_assert( std::conjunction_v< std::is_same<Expect, decltype(InferredTaggedUniformReturnT< absl::IntervalOpenOpenTag, A, B>(0))>, std::is_same<Expect, decltype(InferredTaggedUniformReturnT< - absl::IntervalOpenOpenTag, B, A>(0))>>, - ""); + absl::IntervalOpenOpenTag, B, A>(0))>>); } template <typename A, typename B, typename ExplicitRet> @@ -123,8 +121,7 @@ std::is_same<Expect, decltype(ExplicitUniformReturnT<A, B, Expect>(0))>, std::is_same<Expect, - decltype(ExplicitUniformReturnT<B, A, Expect>(0))>>, - ""); + decltype(ExplicitUniformReturnT<B, A, Expect>(0))>>); static_assert( std::conjunction_v< std::is_same<Expect, @@ -132,8 +129,7 @@ absl::IntervalOpenOpenTag, A, B, Expect>(0))>, std::is_same<Expect, decltype(ExplicitTaggedUniformReturnT< - absl::IntervalOpenOpenTag, B, A, Expect>(0))>>, - ""); + absl::IntervalOpenOpenTag, B, A, Expect>(0))>>); } // Takes the type of `absl::Uniform<R>(gen)` if valid or `Invalid` otherwise.
diff --git a/absl/random/internal/generate_real.h b/absl/random/internal/generate_real.h index e016946..6af0455 100644 --- a/absl/random/internal/generate_real.h +++ b/absl/random/internal/generate_real.h
@@ -85,8 +85,7 @@ static_assert((std::is_same_v<SignedTag, GeneratePositiveTag> || std::is_same_v<SignedTag, GenerateNegativeTag> || - std::is_same_v<SignedTag, GenerateSignedTag>), - ""); + std::is_same_v<SignedTag, GenerateSignedTag>)); static constexpr int kExp = std::numeric_limits<real_type>::digits - 1; static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u;
diff --git a/absl/random/internal/iostream_state_saver.h b/absl/random/internal/iostream_state_saver.h index 7c11a0b..05d9f83 100644 --- a/absl/random/internal/iostream_state_saver.h +++ b/absl/random/internal/iostream_state_saver.h
@@ -223,7 +223,7 @@ template <typename FloatType, typename IStream> inline FloatType read_floating_point(IStream& is) { - static_assert(std::is_floating_point_v<FloatType>, ""); + static_assert(std::is_floating_point_v<FloatType>); FloatType dest; is >> dest; // Parsing a double value may report a subnormal value as an error
diff --git a/absl/random/internal/randen_detect.cc b/absl/random/internal/randen_detect.cc index 7d42c6d..fc77b1c 100644 --- a/absl/random/internal/randen_detect.cc +++ b/absl/random/internal/randen_detect.cc
@@ -20,11 +20,9 @@ #include "absl/random/internal/randen_detect.h" #if defined(__APPLE__) && defined(__aarch64__) -#if defined(__has_include) #if __has_include(<arm/cpu_capabilities_public.h>) #include <arm/cpu_capabilities_public.h> #endif -#endif #include <sys/sysctl.h> #include <sys/types.h> #endif
diff --git a/absl/random/internal/uniform_helper_test.cc b/absl/random/internal/uniform_helper_test.cc index bd5acca..e38b3b1 100644 --- a/absl/random/internal/uniform_helper_test.cc +++ b/absl/random/internal/uniform_helper_test.cc
@@ -217,8 +217,7 @@ static_assert( std::conjunction_v< std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>, - std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>, - ""); + std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>); } TEST_F(UniformHelperTest, UniformTypeInference) {
diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h index 03b0663..81f6ce4 100644 --- a/absl/status/internal/status_internal.h +++ b/absl/status/internal/status_internal.h
@@ -82,6 +82,9 @@ using Payloads = absl::InlinedVector<Payload, 1>; +template <typename T> +using EnableIfString = std::enable_if_t<std::is_same_v<T, std::string>>; + // Reference-counted representation of Status data. class StatusRep { public: @@ -92,16 +95,13 @@ message_(message_arg), payloads_(std::move(payloads_arg)) {} -#ifndef SWIG - template <typename String, - typename = std::enable_if_t<std::is_same_v<String, std::string>>> + template <typename String, typename = EnableIfString<String>> StatusRep(absl::StatusCode code_arg, String&& message_arg, std::unique_ptr<status_internal::Payloads> payloads_arg) : ref_(int32_t{1}), code_(code_arg), message_(std::forward<String>(message_arg)), payloads_(std::move(payloads_arg)) {} -#endif // SWIG absl::StatusCode code() const { return code_; } const std::string& message() const { return message_; }
diff --git a/absl/status/status.cc b/absl/status/status.cc index 155c5d8..555ae42 100644 --- a/absl/status/status.cc +++ b/absl/status/status.cc
@@ -171,7 +171,7 @@ namespace status_internal { // We use an int in the template parameter to shorten mangled names. template <int error_code> -Status MakeErrorImpl(string_view message, SourceLocation loc) { +Status MakeErrorStringViewImpl(string_view message, SourceLocation loc) { return Status(static_cast<StatusCode>(error_code), message, loc); } @@ -179,23 +179,55 @@ // If we add more error code, we need to add their values on this list. // Using ints here instead of static_cast<int>(StatusCode::kFoo) makes it easier // to see that the list is complete. -template Status MakeErrorImpl<0>(string_view, SourceLocation); -template Status MakeErrorImpl<1>(string_view, SourceLocation); -template Status MakeErrorImpl<2>(string_view, SourceLocation); -template Status MakeErrorImpl<3>(string_view, SourceLocation); -template Status MakeErrorImpl<4>(string_view, SourceLocation); -template Status MakeErrorImpl<5>(string_view, SourceLocation); -template Status MakeErrorImpl<6>(string_view, SourceLocation); -template Status MakeErrorImpl<7>(string_view, SourceLocation); -template Status MakeErrorImpl<8>(string_view, SourceLocation); -template Status MakeErrorImpl<9>(string_view, SourceLocation); -template Status MakeErrorImpl<10>(string_view, SourceLocation); -template Status MakeErrorImpl<11>(string_view, SourceLocation); -template Status MakeErrorImpl<12>(string_view, SourceLocation); -template Status MakeErrorImpl<13>(string_view, SourceLocation); -template Status MakeErrorImpl<14>(string_view, SourceLocation); -template Status MakeErrorImpl<15>(string_view, SourceLocation); -template Status MakeErrorImpl<16>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<0>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<1>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<2>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<3>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<4>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<5>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<6>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<7>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<8>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<9>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<10>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<11>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<12>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<13>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<14>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<15>(string_view, SourceLocation); +template Status MakeErrorStringViewImpl<16>(string_view, SourceLocation); + +// Same as above, but for rvalue strings. +#ifndef SWIG +// We use an int in the template parameter to shorten mangled names. +template <int error_code> +Status MakeErrorStringRvalueImpl(std::string&& message, SourceLocation loc) { + return Status(static_cast<StatusCode>(error_code), std::move(message), loc); +} + +// Explicit instantiation for all the error codes. +// If we add more error code, we need to add their values on this list. +// Using ints here instead of static_cast<int>(StatusCode::kFoo) makes it easier +// to see that the list is complete. +template Status MakeErrorStringRvalueImpl<0>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<1>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<2>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<3>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<4>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<5>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<6>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<7>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<8>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<9>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<10>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<11>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<12>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<13>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<14>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<15>(std::string&&, SourceLocation); +template Status MakeErrorStringRvalueImpl<16>(std::string&&, SourceLocation); +#endif // SWIG + } // namespace status_internal bool IsAborted(const Status& status) {
diff --git a/absl/status/status.h b/absl/status/status.h index 3103e79..f86065a 100644 --- a/absl/status/status.h +++ b/absl/status/status.h
@@ -469,8 +469,7 @@ // Same as above but for rvalue string. // Note: using a template to disambiguate the case of matching string_view and // string&& (e.g. char*) as a template lowers the priority of the overload. - template <typename String, - typename = std::enable_if_t<std::is_same_v<String, std::string>>> + template <typename String, typename = status_internal::EnableIfString<String>> Status(absl::StatusCode code, String&& msg, absl::SourceLocation loc = SourceLocation::current()); #endif // SWIG @@ -890,45 +889,176 @@ // These convenience functions create an `absl::Status` object with an error // code as indicated by the associated function name, using the error message // passed in `message`. +// Note: using a template for the rvalue message overload to disambiguate the +// case of matching string_view and string&& (e.g. char*) as a template lowers +// the priority of the overload. + +// AbortedError Status AbortedError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status AbortedError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// AlreadyExistsError Status AlreadyExistsError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status AlreadyExistsError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// CancelledError Status CancelledError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status CancelledError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// DataLossError Status DataLossError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status DataLossError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// DeadlineExceededError Status DeadlineExceededError( absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status DeadlineExceededError( + String&& message, absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// FailedPreconditionError Status FailedPreconditionError( absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status FailedPreconditionError( + String&& message, absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// InternalError Status InternalError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status InternalError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// InvalidArgumentError Status InvalidArgumentError( absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status InvalidArgumentError( + String&& message, absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// NotFoundError Status NotFoundError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status NotFoundError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// OutOfRangeError Status OutOfRangeError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status OutOfRangeError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// PermissionDeniedError Status PermissionDeniedError( absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status PermissionDeniedError( + String&& message, absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// ResourceExhaustedError Status ResourceExhaustedError( absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status ResourceExhaustedError( + String&& message, absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// UnauthenticatedError Status UnauthenticatedError( absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status UnauthenticatedError( + String&& message, absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// UnavailableError Status UnavailableError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status UnavailableError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// UnimplementedError Status UnimplementedError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); + +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status UnimplementedError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + +// UnknownError Status UnknownError(absl::string_view message, absl::SourceLocation loc = SourceLocation::current()); +#ifndef SWIG +template <typename String, typename = status_internal::EnableIfString<String>> +Status UnknownError(String&& message, + absl::SourceLocation loc = SourceLocation::current()); +#endif // SWIG + // ErrnoToStatusCode() // // Returns the StatusCode for `error_number`, which should be an `errno` value. @@ -1143,110 +1273,339 @@ namespace status_internal { // We use an int in the template parameter to shorten mangled names. template <int error_code> -Status MakeErrorImpl(string_view message, SourceLocation loc); +Status MakeErrorStringViewImpl(string_view message, SourceLocation loc); // Make the instantiations extern to reduce bloat on callers. #ifndef SWIG -extern template Status MakeErrorImpl<0>(string_view, SourceLocation); -extern template Status MakeErrorImpl<1>(string_view, SourceLocation); -extern template Status MakeErrorImpl<2>(string_view, SourceLocation); -extern template Status MakeErrorImpl<3>(string_view, SourceLocation); -extern template Status MakeErrorImpl<4>(string_view, SourceLocation); -extern template Status MakeErrorImpl<5>(string_view, SourceLocation); -extern template Status MakeErrorImpl<6>(string_view, SourceLocation); -extern template Status MakeErrorImpl<7>(string_view, SourceLocation); -extern template Status MakeErrorImpl<8>(string_view, SourceLocation); -extern template Status MakeErrorImpl<9>(string_view, SourceLocation); -extern template Status MakeErrorImpl<10>(string_view, SourceLocation); -extern template Status MakeErrorImpl<11>(string_view, SourceLocation); -extern template Status MakeErrorImpl<12>(string_view, SourceLocation); -extern template Status MakeErrorImpl<13>(string_view, SourceLocation); -extern template Status MakeErrorImpl<14>(string_view, SourceLocation); -extern template Status MakeErrorImpl<15>(string_view, SourceLocation); -extern template Status MakeErrorImpl<16>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<0>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<1>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<2>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<3>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<4>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<5>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<6>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<7>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<8>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<9>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<10>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<11>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<12>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<13>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<14>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<15>(string_view, SourceLocation); +extern template Status MakeErrorStringViewImpl<16>(string_view, SourceLocation); #endif // SWIG template <StatusCode error_code> -Status MakeError(string_view message, SourceLocation loc) { - Status out = MakeErrorImpl<static_cast<int>(error_code)>(message, loc); +Status MakeErrorFromStringView(string_view message, SourceLocation loc) { + Status out = + MakeErrorStringViewImpl<static_cast<int>(error_code)>(message, loc); // -Wassume warning complains about potential side effects of `ok()`, so use a // local to avoid that. [[maybe_unused]] bool ok = out.ok(); ABSL_ASSUME(!ok); return out; } + +// Same as above, but for rvalue std::string. +#ifndef SWIG +// We use an int in the template parameter to shorten mangled names. +template <int error_code> +Status MakeErrorStringRvalueImpl(std::string&& message, SourceLocation loc); +// Make the instantiations extern to reduce bloat on callers. +extern template Status MakeErrorStringRvalueImpl<0>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<1>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<2>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<3>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<4>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<5>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<6>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<7>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<8>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<9>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<10>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<11>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<12>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<13>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<14>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<15>(std::string&&, + SourceLocation); +extern template Status MakeErrorStringRvalueImpl<16>(std::string&&, + SourceLocation); + +template <StatusCode error_code, typename String> +Status MakeErrorFromStringRvalue(String&& message, SourceLocation loc) { + static_assert(std::is_same_v<String&&, std::string&&>, + "`message` should be std::string&&"); + Status out = MakeErrorStringRvalueImpl<static_cast<int>(error_code)>( + std::forward<String>(message), loc); + // -Wassume warning complains about potential side effects of `ok()`, so use a + // local to avoid that. + [[maybe_unused]] bool ok = out.ok(); + ABSL_ASSUME(!ok); + return out; +} +#endif // SWIG + } // namespace status_internal // Inline implementations to give the compiler static knowledge about the // objects. + +// AbortedError inline Status AbortedError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kAborted>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kAborted>(message, + loc); } + +#ifndef SWIG +template <typename String, typename> +Status AbortedError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kAborted>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// AlreadyExistsError inline Status AlreadyExistsError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kAlreadyExists>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kAlreadyExists>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status AlreadyExistsError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kAlreadyExists>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// CancelledError inline Status CancelledError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kCancelled>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kCancelled>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status CancelledError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kCancelled>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// DataLossError inline Status DataLossError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kDataLoss>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kDataLoss>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status DataLossError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kDataLoss>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// DeadlineExceededError inline Status DeadlineExceededError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kDeadlineExceeded>(message, - loc); + return status_internal::MakeErrorFromStringView< + StatusCode::kDeadlineExceeded>(message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status DeadlineExceededError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue< + StatusCode::kDeadlineExceeded>(std::forward<String>(message), loc); +} +#endif // SWIG + +// FailedPreconditionError inline Status FailedPreconditionError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kFailedPrecondition>(message, - loc); + return status_internal::MakeErrorFromStringView< + StatusCode::kFailedPrecondition>(message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status FailedPreconditionError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue< + StatusCode::kFailedPrecondition>(std::forward<String>(message), loc); +} +#endif // SWIG + +// InternalError inline Status InternalError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kInternal>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kInternal>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status InternalError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kInternal>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// InvalidArgumentError inline Status InvalidArgumentError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kInvalidArgument>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kInvalidArgument>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status InvalidArgumentError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue< + StatusCode::kInvalidArgument>(std::forward<String>(message), loc); +} +#endif // SWIG + +// NotFoundError inline Status NotFoundError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kNotFound>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kNotFound>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status NotFoundError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kNotFound>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// OutOfRangeError inline Status OutOfRangeError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kOutOfRange>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kOutOfRange>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status OutOfRangeError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kOutOfRange>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// PermissionDeniedError inline Status PermissionDeniedError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kPermissionDenied>(message, - loc); + return status_internal::MakeErrorFromStringView< + StatusCode::kPermissionDenied>(message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status PermissionDeniedError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue< + StatusCode::kPermissionDenied>(std::forward<String>(message), loc); +} +#endif // SWIG + +// ResourceExhaustedError inline Status ResourceExhaustedError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kResourceExhausted>(message, - loc); + return status_internal::MakeErrorFromStringView< + StatusCode::kResourceExhausted>(message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status ResourceExhaustedError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue< + StatusCode::kResourceExhausted>(std::forward<String>(message), loc); +} +#endif // SWIG + +// UnauthenticatedError inline Status UnauthenticatedError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kUnauthenticated>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kUnauthenticated>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status UnauthenticatedError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue< + StatusCode::kUnauthenticated>(std::forward<String>(message), loc); +} +#endif // SWIG + +// UnavailableError inline Status UnavailableError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kUnavailable>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kUnavailable>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status UnavailableError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnavailable>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// UnimplementedError inline Status UnimplementedError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kUnimplemented>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kUnimplemented>( + message, loc); } + +#ifndef SWIG +template <typename String, typename> +Status UnimplementedError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnimplemented>( + std::forward<String>(message), loc); +} +#endif // SWIG + +// UnknownError inline Status UnknownError(absl::string_view message, absl::SourceLocation loc) { - return status_internal::MakeError<StatusCode::kUnknown>(message, loc); + return status_internal::MakeErrorFromStringView<StatusCode::kUnknown>(message, + loc); } +#ifndef SWIG +template <typename String, typename> +Status UnknownError(String&& message, absl::SourceLocation loc) { + return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnknown>( + std::forward<String>(message), loc); +} +#endif // SWIG + ABSL_NAMESPACE_END } // namespace absl
diff --git a/absl/status/status_benchmark.cc b/absl/status/status_benchmark.cc index 0404db1..b001e63 100644 --- a/absl/status/status_benchmark.cc +++ b/absl/status/status_benchmark.cc
@@ -57,4 +57,14 @@ } BENCHMARK(BM_LongMessageRValue); +void BM_LongMessageRValueConvenienceFn(benchmark::State& state) { + for (auto _ : state) { + std::string msg(100, 'X'); + benchmark::DoNotOptimize(msg); + absl::Status s = absl::InvalidArgumentError(std::move(msg)); + benchmark::DoNotOptimize(s); + } +} +BENCHMARK(BM_LongMessageRValueConvenienceFn); + } // namespace
diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc index ddf0be0..c4679d6 100644 --- a/absl/status/status_test.cc +++ b/absl/status/status_test.cc
@@ -19,6 +19,7 @@ #include <array> #include <cstddef> #include <sstream> +#include <string> #include <utility> #include <vector> @@ -46,41 +47,82 @@ } // This structure holds the details for testing a single error code, -// its creator, and its classifier. +// its creator, its rvalue creator, and its classifier. struct ErrorTest { absl::StatusCode code; using Creator = absl::Status (*)(absl::string_view, absl::SourceLocation); - using Classifier = bool (*)(const absl::Status&); Creator creator; + using CreatorRValue = absl::Status (*)(std::string&&, absl::SourceLocation); + CreatorRValue creator_rvalue; + using Classifier = bool (*)(const absl::Status&); Classifier classifier; }; constexpr ErrorTest kErrorTests[]{ - {absl::StatusCode::kCancelled, absl::CancelledError, absl::IsCancelled}, - {absl::StatusCode::kUnknown, absl::UnknownError, absl::IsUnknown}, - {absl::StatusCode::kInvalidArgument, absl::InvalidArgumentError, - absl::IsInvalidArgument}, - {absl::StatusCode::kDeadlineExceeded, absl::DeadlineExceededError, - absl::IsDeadlineExceeded}, - {absl::StatusCode::kNotFound, absl::NotFoundError, absl::IsNotFound}, - {absl::StatusCode::kAlreadyExists, absl::AlreadyExistsError, - absl::IsAlreadyExists}, - {absl::StatusCode::kPermissionDenied, absl::PermissionDeniedError, - absl::IsPermissionDenied}, - {absl::StatusCode::kResourceExhausted, absl::ResourceExhaustedError, - absl::IsResourceExhausted}, - {absl::StatusCode::kFailedPrecondition, absl::FailedPreconditionError, - absl::IsFailedPrecondition}, - {absl::StatusCode::kAborted, absl::AbortedError, absl::IsAborted}, - {absl::StatusCode::kOutOfRange, absl::OutOfRangeError, absl::IsOutOfRange}, - {absl::StatusCode::kUnimplemented, absl::UnimplementedError, - absl::IsUnimplemented}, - {absl::StatusCode::kInternal, absl::InternalError, absl::IsInternal}, - {absl::StatusCode::kUnavailable, absl::UnavailableError, - absl::IsUnavailable}, - {absl::StatusCode::kDataLoss, absl::DataLossError, absl::IsDataLoss}, - {absl::StatusCode::kUnauthenticated, absl::UnauthenticatedError, - absl::IsUnauthenticated}, + {absl::StatusCode::kCancelled, // + absl::CancelledError, // + absl::CancelledError, // + absl::IsCancelled}, // + {absl::StatusCode::kUnknown, // + absl::UnknownError, // + absl::UnknownError, // + absl::IsUnknown}, // + {absl::StatusCode::kInvalidArgument, // + absl::InvalidArgumentError, // + absl::InvalidArgumentError, // + absl::IsInvalidArgument}, // + {absl::StatusCode::kDeadlineExceeded, // + absl::DeadlineExceededError, // + absl::DeadlineExceededError, // + absl::IsDeadlineExceeded}, // + {absl::StatusCode::kNotFound, // + absl::NotFoundError, // + absl::NotFoundError, // + absl::IsNotFound}, // + {absl::StatusCode::kAlreadyExists, // + absl::AlreadyExistsError, // + absl::AlreadyExistsError, // + absl::IsAlreadyExists}, // + {absl::StatusCode::kPermissionDenied, // + absl::PermissionDeniedError, // + absl::PermissionDeniedError, // + absl::IsPermissionDenied}, // + {absl::StatusCode::kResourceExhausted, // + absl::ResourceExhaustedError, // + absl::ResourceExhaustedError, // + absl::IsResourceExhausted}, // + {absl::StatusCode::kFailedPrecondition, // + absl::FailedPreconditionError, // + absl::FailedPreconditionError, // + absl::IsFailedPrecondition}, // + {absl::StatusCode::kAborted, // + absl::AbortedError, // + absl::AbortedError, // + absl::IsAborted}, // + {absl::StatusCode::kOutOfRange, // + absl::OutOfRangeError, // + absl::OutOfRangeError, // + absl::IsOutOfRange}, // + {absl::StatusCode::kUnimplemented, // + absl::UnimplementedError, // + absl::UnimplementedError, // + absl::IsUnimplemented}, // + {absl::StatusCode::kInternal, // + absl::InternalError, // + absl::InternalError, // + absl::IsInternal}, // + {absl::StatusCode::kUnavailable, // + absl::UnavailableError, // + absl::UnavailableError, // + absl::IsUnavailable}, // + {absl::StatusCode::kDataLoss, // + absl::DataLossError, // + absl::DataLossError, // + absl::IsDataLoss}, // + {absl::StatusCode::kUnauthenticated, // + absl::UnauthenticatedError, // + absl::UnauthenticatedError, // + absl::IsUnauthenticated}, // }; TEST(Status, CreateAndClassify) { @@ -96,9 +138,16 @@ EXPECT_EQ(test.code, status.code()); EXPECT_EQ(message, status.message()); + // Testing the rvalue creator. + absl::Status status_rvalue = test.creator_rvalue( + std::string(message), absl::SourceLocation::current()); + EXPECT_EQ(test.code, status_rvalue.code()); + EXPECT_EQ(message, status_rvalue.message()); + // Ensure that the classifier returns true for a status produced by the // creator. EXPECT_TRUE(test.classifier(status)); + EXPECT_TRUE(test.classifier(status_rvalue)); // Ensure that the classifier returns false for status with a different // code. @@ -111,6 +160,37 @@ } } +// Test that status convenience functions can be called with a string literal. +// Doing so to make sure it's not ambiguous between the string_view and string&& +// overloads. +TEST(Status, StringLiteralCreation) { + EXPECT_EQ(absl::AbortedError("msg").code(), absl::StatusCode::kAborted); + EXPECT_EQ(absl::AlreadyExistsError("msg").code(), + absl::StatusCode::kAlreadyExists); + EXPECT_EQ(absl::CancelledError("msg").code(), absl::StatusCode::kCancelled); + EXPECT_EQ(absl::DataLossError("msg").code(), absl::StatusCode::kDataLoss); + EXPECT_EQ(absl::DeadlineExceededError("msg").code(), + absl::StatusCode::kDeadlineExceeded); + EXPECT_EQ(absl::FailedPreconditionError("msg").code(), + absl::StatusCode::kFailedPrecondition); + EXPECT_EQ(absl::InternalError("msg").code(), absl::StatusCode::kInternal); + EXPECT_EQ(absl::InvalidArgumentError("msg").code(), + absl::StatusCode::kInvalidArgument); + EXPECT_EQ(absl::NotFoundError("msg").code(), absl::StatusCode::kNotFound); + EXPECT_EQ(absl::OutOfRangeError("msg").code(), absl::StatusCode::kOutOfRange); + EXPECT_EQ(absl::PermissionDeniedError("msg").code(), + absl::StatusCode::kPermissionDenied); + EXPECT_EQ(absl::ResourceExhaustedError("msg").code(), + absl::StatusCode::kResourceExhausted); + EXPECT_EQ(absl::UnauthenticatedError("msg").code(), + absl::StatusCode::kUnauthenticated); + EXPECT_EQ(absl::UnavailableError("msg").code(), + absl::StatusCode::kUnavailable); + EXPECT_EQ(absl::UnimplementedError("msg").code(), + absl::StatusCode::kUnimplemented); + EXPECT_EQ(absl::UnknownError("msg").code(), absl::StatusCode::kUnknown); +} + TEST(Status, DefaultConstructor) { absl::Status status; EXPECT_TRUE(status.ok()); @@ -340,37 +420,37 @@ TEST(Status, OstreamOperator) { absl::Status status(absl::StatusCode::kInternal, "fail"); - { std::stringstream stream; + { + std::stringstream stream; stream << status; - EXPECT_THAT(stream.str(), - AllOf(HasSubstr("INTERNAL: fail"), - HasSubstr("status_test.cc:"))); + EXPECT_THAT(stream.str(), AllOf(HasSubstr("INTERNAL: fail"), + HasSubstr("status_test.cc:"))); } status.SetPayload("foo", absl::Cord("bar")); - { std::stringstream stream; + { + std::stringstream stream; stream << status; EXPECT_THAT(stream.str(), AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), HasSubstr("status_test.cc:"))); } status.SetPayload("bar", absl::Cord("\377")); - { std::stringstream stream; + { + std::stringstream stream; stream << status; - EXPECT_THAT(stream.str(), - AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), - HasSubstr("[bar='\\xff']"), - HasSubstr("status_test.cc:"))); + EXPECT_THAT( + stream.str(), + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), + HasSubstr("[bar='\\xff']"), HasSubstr("status_test.cc:"))); } } TEST(Status, AbslStringify) { absl::Status status(absl::StatusCode::kInternal, "fail"); EXPECT_THAT(absl::StrCat(status), - AllOf(HasSubstr("INTERNAL: fail"), - HasSubstr("status_test.cc:"))); + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("status_test.cc:"))); EXPECT_THAT(absl::StrFormat("%v", status), - AllOf(HasSubstr("INTERNAL: fail"), - HasSubstr("status_test.cc:"))); + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("status_test.cc:"))); EXPECT_EQ(absl::StrCat(status), absl::StrFormat("%v", status)); status.SetPayload("foo", absl::Cord("bar")); EXPECT_THAT(absl::StrCat(status), @@ -379,8 +459,7 @@ status.SetPayload("bar", absl::Cord("\377")); EXPECT_THAT(absl::StrCat(status), AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), - HasSubstr("[bar='\\xff']"), - HasSubstr("status_test.cc:"))); + HasSubstr("[bar='\\xff']"), HasSubstr("status_test.cc:"))); } TEST(Status, OstreamEqStringify) { @@ -867,8 +946,7 @@ { // Status that ignores source location. absl::Status status_ignores_source_location[] = { - absl::Status(), - absl::Status(absl::StatusCode::kInternal, "")}; + absl::Status(), absl::Status(absl::StatusCode::kInternal, "")}; for (absl::Status& s : status_ignores_source_location) { for (int i = 0; i < max_iter; ++i) { s.AddSourceLocation(absl::SourceLocation::current()); @@ -967,27 +1045,27 @@ s.SetPayload("bar", absl::Cord("\377")); - EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithEverything), - AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), - HasSubstr("[bar='\\xff']"), - HasSubstr(source_location_string), - HasSubstr(source_location_stack))); - EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithPayload | - absl::StatusToStringMode::kWithSourceLocation), - AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), - HasSubstr("[bar='\\xff']"), - HasSubstr(source_location_string), - HasSubstr(source_location_stack))); - EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithSourceLocation), - AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")), - Not(HasSubstr("[bar='\\xff']")), - HasSubstr(source_location_string), - HasSubstr(source_location_stack))); - EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithPayload), - AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), - HasSubstr("[bar='\\xff']"), - Not(HasSubstr(source_location_string)), - Not(HasSubstr(source_location_stack)))); + EXPECT_THAT( + s.ToString(absl::StatusToStringMode::kWithEverything), + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), + HasSubstr("[bar='\\xff']"), HasSubstr(source_location_string), + HasSubstr(source_location_stack))); + EXPECT_THAT( + s.ToString(absl::StatusToStringMode::kWithPayload | + absl::StatusToStringMode::kWithSourceLocation), + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), + HasSubstr("[bar='\\xff']"), HasSubstr(source_location_string), + HasSubstr(source_location_stack))); + EXPECT_THAT( + s.ToString(absl::StatusToStringMode::kWithSourceLocation), + AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")), + Not(HasSubstr("[bar='\\xff']")), HasSubstr(source_location_string), + HasSubstr(source_location_stack))); + EXPECT_THAT( + s.ToString(absl::StatusToStringMode::kWithPayload), + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), + HasSubstr("[bar='\\xff']"), Not(HasSubstr(source_location_string)), + Not(HasSubstr(source_location_stack)))); } TEST(Status, StackTracePayloadOverflow) {
diff --git a/absl/status/statusor_test.cc b/absl/status/statusor_test.cc index 51f3750..8a95049 100644 --- a/absl/status/statusor_test.cc +++ b/absl/status/statusor_test.cc
@@ -118,8 +118,8 @@ } TEST(StatusOr, ElementType) { - static_assert(std::is_same<absl::StatusOr<int>::value_type, int>(), ""); - static_assert(std::is_same<absl::StatusOr<char>::value_type, char>(), ""); + static_assert(std::is_same<absl::StatusOr<int>::value_type, int>()); + static_assert(std::is_same<absl::StatusOr<char>::value_type, char>()); } TEST(StatusOr, TestMoveOnlyInitialization) { @@ -1393,7 +1393,7 @@ TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) { using EvilType = std::vector<std::unique_ptr<int>>; - static_assert(std::is_copy_constructible_v<EvilType>, ""); + static_assert(std::is_copy_constructible_v<EvilType>); std::vector<::absl::StatusOr<EvilType>> v(5); v.reserve(v.capacity() + 10); v.resize(v.capacity() + 10);
diff --git a/absl/strings/cord.h b/absl/strings/cord.h index 7e80259..fad5d97 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h
@@ -177,7 +177,7 @@ // Additionally, the API provides iterator utilities to iterate through Cord // data via chunks or character bytes. // -class Cord { +class ABSL_ATTRIBUTE_TRIVIAL_ABI Cord { private: template <typename T> using EnableIfString = std::enable_if_t<std::is_same_v<T, std::string>, int>; @@ -915,10 +915,10 @@ // to the representation. // // InlineRep holds either a tree pointer, or an array of kMaxInline bytes. - class InlineRep { + class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineRep { public: static constexpr unsigned char kMaxInline = cord_internal::kMaxInline; - static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), ""); + static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*)); constexpr InlineRep() : data_() {} explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {} @@ -1124,7 +1124,6 @@ void CopyToArrayImpl(char* absl_nonnull dst) const; }; - // allow a Cord to be logged extern std::ostream& operator<<(std::ostream& out, const Cord& cord); @@ -1285,7 +1284,7 @@ inline cord_internal::CordRepFlat* absl_nonnull Cord::InlineRep::MakeFlatWithExtraCapacity(size_t extra) { - static_assert(cord_internal::kMinFlatLength >= sizeof(data_), ""); + static_assert(cord_internal::kMinFlatLength >= sizeof(data_)); size_t len = data_.inline_size(); auto* result = CordRepFlat::New(len + extra); result->length = len;
diff --git a/absl/strings/cord_buffer.h b/absl/strings/cord_buffer.h index fc806bb..a2d1b32 100644 --- a/absl/strings/cord_buffer.h +++ b/absl/strings/cord_buffer.h
@@ -290,7 +290,7 @@ private: // Make sure we don't accidentally over promise. - static_assert(kCustomLimit <= cord_internal::kMaxLargeFlatSize, ""); + static_assert(kCustomLimit <= cord_internal::kMaxLargeFlatSize); // Assume the cost of an 'uprounded' allocation to CeilPow2(size) versus // the cost of allocating at least 1 extra flat <= 4KB:
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc index cf65453..7a2c936 100644 --- a/absl/strings/cord_test.cc +++ b/absl/strings/cord_test.cc
@@ -277,9 +277,9 @@ TEST(CordRepFlat, AllFlatCapacities) { // Explicitly and redundantly assert built-in min/max limits - static_assert(absl::cord_internal::kFlatOverhead < 32, ""); - static_assert(absl::cord_internal::kMinFlatSize == 32, ""); - static_assert(absl::cord_internal::kMaxLargeFlatSize == 256 << 10, ""); + static_assert(absl::cord_internal::kFlatOverhead < 32); + static_assert(absl::cord_internal::kMinFlatSize == 32); + static_assert(absl::cord_internal::kMaxLargeFlatSize == 256 << 10); EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(FLAT), 32); EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(MAX_FLAT_TAG), 256 << 10); @@ -2364,35 +2364,30 @@ } TEST_P(CordTest, CordChunkIteratorTraits) { - static_assert(std::is_copy_constructible_v<absl::Cord::ChunkIterator>, ""); - static_assert(std::is_copy_assignable_v<absl::Cord::ChunkIterator>, ""); + static_assert(std::is_copy_constructible_v<absl::Cord::ChunkIterator>); + static_assert(std::is_copy_assignable_v<absl::Cord::ChunkIterator>); // Move semantics to satisfy swappable via std::swap - static_assert(std::is_move_constructible_v<absl::Cord::ChunkIterator>, ""); - static_assert(std::is_move_assignable_v<absl::Cord::ChunkIterator>, ""); + static_assert(std::is_move_constructible_v<absl::Cord::ChunkIterator>); + static_assert(std::is_move_assignable_v<absl::Cord::ChunkIterator>); static_assert( std::is_same_v< std::iterator_traits<absl::Cord::ChunkIterator>::iterator_category, - std::input_iterator_tag>, - ""); + std::input_iterator_tag>); static_assert(std::is_same_v< - std::iterator_traits<absl::Cord::ChunkIterator>::value_type, - absl::string_view>, - ""); + std::iterator_traits<absl::Cord::ChunkIterator>::value_type, + absl::string_view>); static_assert( std::is_same_v< std::iterator_traits<absl::Cord::ChunkIterator>::difference_type, - ptrdiff_t>, - ""); + ptrdiff_t>); static_assert( std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::pointer, - const absl::string_view*>, - ""); + const absl::string_view*>); static_assert( std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::reference, - absl::string_view>, - ""); + absl::string_view>); } static void VerifyChunkIterator(const absl::Cord& cord, @@ -2551,35 +2546,29 @@ } TEST_P(CordTest, CharIteratorTraits) { - static_assert(std::is_copy_constructible_v<absl::Cord::CharIterator>, ""); - static_assert(std::is_copy_assignable_v<absl::Cord::CharIterator>, ""); + static_assert(std::is_copy_constructible_v<absl::Cord::CharIterator>); + static_assert(std::is_copy_assignable_v<absl::Cord::CharIterator>); // Move semantics to satisfy swappable via std::swap - static_assert(std::is_move_constructible_v<absl::Cord::CharIterator>, ""); - static_assert(std::is_move_assignable_v<absl::Cord::CharIterator>, ""); + static_assert(std::is_move_constructible_v<absl::Cord::CharIterator>); + static_assert(std::is_move_assignable_v<absl::Cord::CharIterator>); static_assert( std::is_same_v< std::iterator_traits<absl::Cord::CharIterator>::iterator_category, - std::input_iterator_tag>, - ""); + std::input_iterator_tag>); static_assert( std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::value_type, - char>, - ""); - static_assert( - std::is_same_v< - std::iterator_traits<absl::Cord::CharIterator>::difference_type, - ptrdiff_t>, - ""); + char>); + static_assert(std::is_same_v< + std::iterator_traits<absl::Cord::CharIterator>::difference_type, + ptrdiff_t>); static_assert( std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::pointer, - const char*>, - ""); + const char*>); static_assert( std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::reference, - const char&>, - ""); + const char&>); } static void VerifyCharIterator(const absl::Cord& cord) {
diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index 98dc4b5..650f514 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h
@@ -35,8 +35,11 @@ #include "absl/strings/string_view.h" // We can only add poisoning if we can detect consteval executions. -#if defined(ABSL_HAVE_CONSTANT_EVALUATED) && \ - (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ +// +// TODO(b/548049702): attempt to turn this back on. It's disabled because asan +// interacts poorly with trivial ABIs (http://b/546331925). +#if 0 && defined(ABSL_HAVE_CONSTANT_EVALUATED) && \ + (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ defined(ABSL_HAVE_MEMORY_SANITIZER)) #define ABSL_INTERNAL_CORD_HAVE_SANITIZER 1 #endif @@ -465,8 +468,8 @@ // Assert that the `cordz_info` pointer value perfectly overlaps the last half // of `data` and can hold a pointer value. -static_assert(sizeof(cordz_info_t) * 2 == kMaxInline + 1, ""); -static_assert(sizeof(cordz_info_t) >= sizeof(intptr_t), ""); +static_assert(sizeof(cordz_info_t) * 2 == kMaxInline + 1); +static_assert(sizeof(cordz_info_t) >= sizeof(intptr_t)); // LittleEndianByte() creates a little endian representation of 'value', i.e.: // a little endian value where the first byte in the host's representation @@ -479,7 +482,7 @@ #endif } -class InlineData { +class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineData { public: // DefaultInitType forces the use of the default initialization constructor. enum DefaultInitType { kDefaultInit }; @@ -516,7 +519,7 @@ // value. Creates an inlined SSO value if `rep` is null, otherwise // creates a tree instance value. constexpr InlineData(absl::string_view sv, CordRep* rep) noexcept - : rep_(rep ? Rep(rep) : Rep(sv)) { + : rep_(rep != nullptr ? Rep(rep) : Rep(sv)) { poison(); } @@ -833,7 +836,7 @@ Rep rep_; }; -static_assert(sizeof(InlineData) == kMaxInline + 1, ""); +static_assert(sizeof(InlineData) == kMaxInline + 1); #ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
diff --git a/absl/strings/internal/cord_rep_btree.cc b/absl/strings/internal/cord_rep_btree.cc index 92e6450..d816522 100644 --- a/absl/strings/internal/cord_rep_btree.cc +++ b/absl/strings/internal/cord_rep_btree.cc
@@ -278,7 +278,7 @@ return tree; case CordRepBtree::kCopied: CordRep::Unref(tree); - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case CordRepBtree::kSelf: return result.tree; }
diff --git a/absl/strings/internal/cord_rep_btree.h b/absl/strings/internal/cord_rep_btree.h index ab259af..852cc17 100644 --- a/absl/strings/internal/cord_rep_btree.h +++ b/absl/strings/internal/cord_rep_btree.h
@@ -865,16 +865,16 @@ tree = tree->Edge(kBack)->btree(); if (!tree->refcount.IsOne()) return {}; n2 = tree; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case 2: tree = tree->Edge(kBack)->btree(); if (!tree->refcount.IsOne()) return {}; n1 = tree; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case 1: tree = tree->Edge(kBack)->btree(); if (!tree->refcount.IsOne()) return {}; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case 0: CordRep* edge = tree->Edge(kBack); if (!edge->refcount.IsOne()) return {}; @@ -887,13 +887,13 @@ switch (height) { case 3: n3->length += delta; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case 2: n2->length += delta; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case 1: n1->length += delta; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case 0: tree->length += delta; return span;
diff --git a/absl/strings/internal/cord_rep_flat.h b/absl/strings/internal/cord_rep_flat.h index 27c4b21..3cdeca6 100644 --- a/absl/strings/internal/cord_rep_flat.h +++ b/absl/strings/internal/cord_rep_flat.h
@@ -69,9 +69,8 @@ ((512 / 8) + ((8192 - 512) / 64)) * 4096; } -static_assert(AllocatedSizeToTagUnchecked(kMinFlatSize) == FLAT, ""); -static_assert(AllocatedSizeToTagUnchecked(kMaxLargeFlatSize) == MAX_FLAT_TAG, - ""); +static_assert(AllocatedSizeToTagUnchecked(kMinFlatSize) == FLAT); +static_assert(AllocatedSizeToTagUnchecked(kMaxLargeFlatSize) == MAX_FLAT_TAG); // RoundUp logically performs `((n + m - 1) / m) * m` to round up to the nearest // multiple of `m`, optimized for the invariant that `m` is a power of 2.
diff --git a/absl/strings/internal/cordz_sample_token_test.cc b/absl/strings/internal/cordz_sample_token_test.cc index 22ef21c..ccb28d0 100644 --- a/absl/strings/internal/cordz_sample_token_test.cc +++ b/absl/strings/internal/cordz_sample_token_test.cc
@@ -44,33 +44,27 @@ auto constexpr kTrackCordMethod = CordzUpdateTracker::kConstructorString; TEST(CordzSampleTokenTest, IteratorTraits) { - static_assert(std::is_copy_constructible_v<CordzSampleToken::Iterator>, ""); - static_assert(std::is_copy_assignable_v<CordzSampleToken::Iterator>, ""); - static_assert(std::is_move_constructible_v<CordzSampleToken::Iterator>, ""); - static_assert(std::is_move_assignable_v<CordzSampleToken::Iterator>, ""); + static_assert(std::is_copy_constructible_v<CordzSampleToken::Iterator>); + static_assert(std::is_copy_assignable_v<CordzSampleToken::Iterator>); + static_assert(std::is_move_constructible_v<CordzSampleToken::Iterator>); + static_assert(std::is_move_assignable_v<CordzSampleToken::Iterator>); static_assert( std::is_same_v< std::iterator_traits<CordzSampleToken::Iterator>::iterator_category, - std::input_iterator_tag>, - ""); - static_assert( - std::is_same_v< - std::iterator_traits<CordzSampleToken::Iterator>::value_type, - const CordzInfo&>, - ""); + std::input_iterator_tag>); + static_assert(std::is_same_v< + std::iterator_traits<CordzSampleToken::Iterator>::value_type, + const CordzInfo&>); static_assert( std::is_same_v< std::iterator_traits<CordzSampleToken::Iterator>::difference_type, - ptrdiff_t>, - ""); + ptrdiff_t>); static_assert( std::is_same_v<std::iterator_traits<CordzSampleToken::Iterator>::pointer, - const CordzInfo*>, - ""); + const CordzInfo*>); static_assert(std::is_same_v< - std::iterator_traits<CordzSampleToken::Iterator>::reference, - const CordzInfo&>, - ""); + std::iterator_traits<CordzSampleToken::Iterator>::reference, + const CordzInfo&>); } TEST(CordzSampleTokenTest, IteratorEmpty) {
diff --git a/absl/strings/internal/ostringstream_test.cc b/absl/strings/internal/ostringstream_test.cc index ef3ad57..c0f88c1 100644 --- a/absl/strings/internal/ostringstream_test.cc +++ b/absl/strings/internal/ostringstream_test.cc
@@ -27,8 +27,7 @@ TEST(OStringStream, IsOStream) { static_assert( - std::is_base_of<std::ostream, absl::strings_internal::OStringStream>(), - ""); + std::is_base_of<std::ostream, absl::strings_internal::OStringStream>()); } TEST(OStringStream, ConstructNullptr) { @@ -83,8 +82,8 @@ absl::strings_internal::OStringStream strm(&s1); const absl::strings_internal::OStringStream& c_strm(strm); - static_assert(std::is_same<decltype(strm.str()), std::string*>(), ""); - static_assert(std::is_same<decltype(c_strm.str()), const std::string*>(), ""); + static_assert(std::is_same<decltype(strm.str()), std::string*>()); + static_assert(std::is_same<decltype(c_strm.str()), const std::string*>()); EXPECT_EQ(&s1, strm.str()); EXPECT_EQ(&s1, c_strm.str());
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc index 0687b4e..2125be3 100644 --- a/absl/strings/internal/str_format/arg.cc +++ b/absl/strings/internal/str_format/arg.cc
@@ -82,7 +82,7 @@ // Supports unsigned integral types and uint128. template <typename T> void PrintAsOct(T v) { - static_assert(!IsSigned<T>::value, ""); + static_assert(!IsSigned<T>::value); char *p = storage_ + sizeof(storage_); do { *--p = static_cast<char>('0' + (static_cast<size_t>(v) & 7)); @@ -96,7 +96,7 @@ // Supports all integral types. template <typename T> void PrintAsDec(T v) { - static_assert(std::is_integral_v<T>, ""); + static_assert(std::is_integral_v<T>); start_ = storage_; size_ = static_cast<size_t>(numbers_internal::FastIntToBuffer(v, storage_) - storage_); @@ -136,7 +136,7 @@ // Supports unsigned integral types and uint128. template <typename T> void PrintAsHexLower(T v) { - static_assert(!IsSigned<T>::value, ""); + static_assert(!IsSigned<T>::value); char *p = storage_ + sizeof(storage_); do { @@ -158,7 +158,7 @@ // Supports unsigned integral types and uint128. template <typename T> void PrintAsHexUpper(T v) { - static_assert(!IsSigned<T>::value, ""); + static_assert(!IsSigned<T>::value); char *p = storage_ + sizeof(storage_); // kHexTable is only lowercase, so do it manually for uppercase.
diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc index 87e23b5..689fa5c 100644 --- a/absl/strings/internal/str_format/bind.cc +++ b/absl/strings/internal/str_format/bind.cc
@@ -251,7 +251,7 @@ errno = sink.error(); return -1; } - if (sink.count() > static_cast<size_t>(std::numeric_limits<int>::max())) { + if (sink.count() > size_t{std::numeric_limits<int>::max()}) { errno = EFBIG; return -1; } @@ -267,6 +267,10 @@ } size_t total = sink.total_written(); if (size) output[std::min(total, size - 1)] = 0; + if (total > size_t{std::numeric_limits<int>::max()}) { + errno = EFBIG; + return -1; + } return static_cast<int>(total); }
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h index 173284c..0e0b262 100644 --- a/absl/strings/internal/str_format/extension.h +++ b/absl/strings/internal/str_format/extension.h
@@ -290,7 +290,7 @@ FormatConversionChar conversion_char() const { // Keep this field first in the struct . It generates better code when // accessing it when ConversionSpec is passed by value in registers. - static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0, ""); + static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0); return conv_; }
diff --git a/absl/strings/internal/str_format/float_conversion.cc b/absl/strings/internal/str_format/float_conversion.cc index f69b8ef..137e159 100644 --- a/absl/strings/internal/str_format/float_conversion.cc +++ b/absl/strings/internal/str_format/float_conversion.cc
@@ -149,8 +149,7 @@ assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent); static_assert( StackArray::kMaxCapacity >= - ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent), - ""); + ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent)); StackArray::RunWithCapacity( ChunksNeeded(exp), @@ -267,8 +266,7 @@ const int margin = Limits::digits + 128; assert(-exp >= Limits::min_exponent - margin); static_assert(StackArray::kMaxCapacity >= - ChunksNeeded(margin - Limits::min_exponent), - ""); + ChunksNeeded(margin - Limits::min_exponent)); StackArray::RunWithCapacity( ChunksNeeded(exp), [=](absl::Span<uint32_t> input) { f(FractionalDigitGenerator(input, v, exp)); @@ -1178,8 +1176,7 @@ struct Decomposed { using MantissaType = std::conditional_t<std::is_same_v<long double, Float>, uint128, uint64_t>; - static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8, - ""); + static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8); MantissaType mantissa; int exponent; };
diff --git a/absl/strings/internal/str_split_internal.h b/absl/strings/internal/str_split_internal.h index bda084b..4e29790 100644 --- a/absl/strings/internal/str_split_internal.h +++ b/absl/strings/internal/str_split_internal.h
@@ -244,16 +244,14 @@ template <typename StringType, typename First, typename Second> using ShouldUseLifetimeBoundForPair = - std::integral_constant<bool, - std::is_same_v<StringType, std::string> && - (std::is_same_v<First, absl::string_view> || - std::is_same_v<Second, absl::string_view>)>; + std::bool_constant<std::is_same_v<StringType, std::string> && + (std::is_same_v<First, absl::string_view> || + std::is_same_v<Second, absl::string_view>)>; template <typename StringType, typename ElementType, std::size_t Size> using ShouldUseLifetimeBoundForArray = - std::integral_constant<bool, - std::is_same_v<StringType, std::string> && - std::is_same_v<ElementType, absl::string_view>>; + std::bool_constant<std::is_same_v<StringType, std::string> && + std::is_same_v<ElementType, absl::string_view>>; // This class implements the range that is returned by absl::StrSplit(). This // class has templated conversion operators that allow it to be implicitly
diff --git a/absl/strings/numbers.cc b/absl/strings/numbers.cc index 479c07e..924c912 100644 --- a/absl/strings/numbers.cc +++ b/absl/strings/numbers.cc
@@ -1124,15 +1124,15 @@ case -4: out[2] = '0'; ++out; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case -3: out[2] = '0'; ++out; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case -2: out[2] = '0'; ++out; - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case -1: out += 2; memcpy(out, &digits[0], 6);
diff --git a/absl/strings/str_format.h b/absl/strings/str_format.h index d02fe20..6ec289e 100644 --- a/absl/strings/str_format.h +++ b/absl/strings/str_format.h
@@ -309,9 +309,8 @@ // ... error case ... // } -#if defined(__cpp_nontype_template_parameter_auto) -// If C++17 is available, an 'extended' format is also allowed that can specify -// multiple conversion characters per format argument, using a combination of +// An 'extended' format is also allowed that can specify multiple conversion +// characters per format argument, using a combination of // `absl::FormatConversionCharSet` enum values (logically a set union) // via the `|` operator. (Single character-based arguments are still accepted, // but cannot be combined). Some common conversions also have predefined enum @@ -333,11 +332,6 @@ template <auto... Conv> using ParsedFormat = absl::str_format_internal::ExtendedParsedFormat< absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; -#else -template <char... Conv> -using ParsedFormat = str_format_internal::ExtendedParsedFormat< - absl::str_format_internal::ToFormatConversionCharSet(Conv)...>; -#endif // defined(__cpp_nontype_template_parameter_auto) // StrFormat() //
diff --git a/absl/strings/str_format_test.cc b/absl/strings/str_format_test.cc index 019284b..a0db73f 100644 --- a/absl/strings/str_format_test.cc +++ b/absl/strings/str_format_test.cc
@@ -524,6 +524,19 @@ EXPECT_EQ(buffer[0], '\0'); } +TEST_F(FormatEntryPointTest, SNPrintFTooLarge) { + // Formatting more than INT_MAX bytes cannot be represented in the int return + // value, so the call reports an error via errno rather than returning a + // truncated (and possibly negative) count, matching FPrintF. A zero size + // means nothing is written to the buffer. + char buffer[16]; + int width = 2000000000; + errno = 0; + int result = SNPrintF(buffer, 0, "%*d %*d", width, 0, width, 0); + EXPECT_LT(result, 0); + EXPECT_EQ(errno, EFBIG); +} + TEST_F(FormatEntryPointTest, SNPrintFWithV) { char buffer[16]; int result =
diff --git a/absl/strings/str_split_test.cc b/absl/strings/str_split_test.cc index 57aa87e..8155311 100644 --- a/absl/strings/str_split_test.cc +++ b/absl/strings/str_split_test.cc
@@ -48,31 +48,23 @@ using ::testing::UnorderedElementsAre; TEST(Split, TraitsTest) { - static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value, - ""); + static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value); static_assert( - !absl::strings_internal::SplitterIsConvertibleTo<std::string>::value, ""); + !absl::strings_internal::SplitterIsConvertibleTo<std::string>::value); static_assert(absl::strings_internal::SplitterIsConvertibleTo< - std::vector<std::string>>::value, - ""); - static_assert( - !absl::strings_internal::SplitterIsConvertibleTo<std::vector<int>>::value, - ""); - static_assert(absl::strings_internal::SplitterIsConvertibleTo< - std::vector<absl::string_view>>::value, - ""); - static_assert(absl::strings_internal::SplitterIsConvertibleTo< - std::map<std::string, std::string>>::value, - ""); - static_assert(absl::strings_internal::SplitterIsConvertibleTo< - std::map<absl::string_view, absl::string_view>>::value, - ""); + std::vector<std::string>>::value); static_assert(!absl::strings_internal::SplitterIsConvertibleTo< - std::map<int, std::string>>::value, - ""); + std::vector<int>>::value); + static_assert(absl::strings_internal::SplitterIsConvertibleTo< + std::vector<absl::string_view>>::value); + static_assert(absl::strings_internal::SplitterIsConvertibleTo< + std::map<std::string, std::string>>::value); + static_assert(absl::strings_internal::SplitterIsConvertibleTo< + std::map<absl::string_view, absl::string_view>>::value); static_assert(!absl::strings_internal::SplitterIsConvertibleTo< - std::map<std::string, int>>::value, - ""); + std::map<int, std::string>>::value); + static_assert(!absl::strings_internal::SplitterIsConvertibleTo< + std::map<std::string, int>>::value); } // This tests the overall split API, which is made up of the absl::StrSplit()
diff --git a/absl/synchronization/BUILD.bazel b/absl/synchronization/BUILD.bazel index 942fc03..57740ef 100644 --- a/absl/synchronization/BUILD.bazel +++ b/absl/synchronization/BUILD.bazel
@@ -49,6 +49,7 @@ }), linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ + "//absl/algorithm:container", "//absl/base", "//absl/base:base_internal", "//absl/base:config", @@ -69,9 +70,7 @@ "@do_not_use_for_gloop_visibility_only//gloop/thread:__subpackages__", ], deps = [ - "//absl/base", "//absl/base:config", - "//absl/base:core_headers", "//absl/base:raw_logging_internal", "//absl/time", ], @@ -85,8 +84,6 @@ linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":kernel_timeout_internal", - "//absl/base:config", - "//absl/random", "//absl/time", "@googletest//:gtest", "@googletest//:gtest_main", @@ -215,7 +212,9 @@ linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":graphcycles_internal", + "//absl/base:config", "//absl/base:core_headers", + "//absl/container:flat_hash_set", "//absl/log", "//absl/log:check", "@googletest//:gtest", @@ -264,12 +263,10 @@ deps = [ ":synchronization", ":thread_pool", - "//absl/base", "//absl/base:config", "//absl/base:core_headers", "//absl/log", "//absl/log:check", - "//absl/memory", "//absl/random", "//absl/time", "@googletest//:gtest", @@ -284,7 +281,6 @@ linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":synchronization", - "//absl/base:config", "@googletest//:gtest", "@googletest//:gtest_main", ], @@ -302,8 +298,8 @@ ":synchronization", ":thread_pool", "//absl/base", - "//absl/base:config", "//absl/base:no_destructor", + "//absl/base:raw_logging_internal", "@google_benchmark//:benchmark_main", ], alwayslink = 1, @@ -348,9 +344,11 @@ "@do_not_use_for_gloop_visibility_only//gloop/base:__subpackages__", ], deps = [ + ":kernel_timeout_internal", ":synchronization", "//absl/base", "//absl/base:config", + "//absl/base:core_headers", "//absl/strings", "//absl/time", "@googletest//:gtest", @@ -386,7 +384,6 @@ ":kernel_timeout_internal", ":synchronization", ":thread_pool", - "//absl/base:config", "//absl/random", "//absl/time", "@googletest//:gtest",
diff --git a/absl/synchronization/CMakeLists.txt b/absl/synchronization/CMakeLists.txt index 9c4a0b1..2805000 100644 --- a/absl/synchronization/CMakeLists.txt +++ b/absl/synchronization/CMakeLists.txt
@@ -157,6 +157,7 @@ DEPS absl::check absl::core_headers + absl::flat_hash_map absl::graphcycles_internal absl::log GTest::gmock_main
diff --git a/absl/synchronization/barrier.cc b/absl/synchronization/barrier.cc index f5dad22..e5cbdc6 100644 --- a/absl/synchronization/barrier.cc +++ b/absl/synchronization/barrier.cc
@@ -14,6 +14,7 @@ #include "absl/synchronization/barrier.h" +#include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" #include "absl/synchronization/mutex.h"
diff --git a/absl/synchronization/barrier_test.cc b/absl/synchronization/barrier_test.cc index 2aed272..2cfb57c 100644 --- a/absl/synchronization/barrier_test.cc +++ b/absl/synchronization/barrier_test.cc
@@ -20,7 +20,7 @@ #include "gtest/gtest.h" #include "absl/synchronization/mutex.h" #include "absl/time/clock.h" - +#include "absl/time/time.h" TEST(Barrier, SanityTest) { constexpr int kNumThreads = 10;
diff --git a/absl/synchronization/blocking_counter.cc b/absl/synchronization/blocking_counter.cc index 9468469..d38b260 100644 --- a/absl/synchronization/blocking_counter.cc +++ b/absl/synchronization/blocking_counter.cc
@@ -16,8 +16,10 @@ #include <atomic> +#include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/tracing.h" +#include "absl/synchronization/mutex.h" namespace absl { ABSL_NAMESPACE_BEGIN
diff --git a/absl/synchronization/blocking_counter.h b/absl/synchronization/blocking_counter.h index d0504a1..46c010b 100644 --- a/absl/synchronization/blocking_counter.h +++ b/absl/synchronization/blocking_counter.h
@@ -91,7 +91,7 @@ private: // Convenience helper to reduce verbosity at call sites. - static inline constexpr base_internal::ObjectKind TraceObjectKind() { + static constexpr base_internal::ObjectKind TraceObjectKind() { return base_internal::ObjectKind::kBlockingCounter; }
diff --git a/absl/synchronization/internal/create_thread_identity.cc b/absl/synchronization/internal/create_thread_identity.cc index e10d3bc..d7168da 100644 --- a/absl/synchronization/internal/create_thread_identity.cc +++ b/absl/synchronization/internal/create_thread_identity.cc
@@ -12,18 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include <stdint.h> - -#include <new> +#include "absl/base/internal/low_level_alloc.h" // IWYU pragma: keep // This file is a no-op if the required LowLevelAlloc support is missing. -#include "absl/base/internal/low_level_alloc.h" -#include "absl/synchronization/internal/waiter.h" #ifndef ABSL_LOW_LEVEL_ALLOC_MISSING -#include <string.h> +#include <atomic> +#include <cstdint> +#include <new> #include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/internal/scheduling_mode.h" #include "absl/base/internal/spinlock.h" #include "absl/base/internal/thread_identity.h" #include "absl/synchronization/internal/per_thread_sem.h"
diff --git a/absl/synchronization/internal/futex_waiter.cc b/absl/synchronization/internal/futex_waiter.cc index 8945c17..d7666d9 100644 --- a/absl/synchronization/internal/futex_waiter.cc +++ b/absl/synchronization/internal/futex_waiter.cc
@@ -17,15 +17,14 @@ #ifdef ABSL_INTERNAL_HAVE_FUTEX_WAITER #include <atomic> -#include <cstdint> #include <cerrno> +#include <cstdint> #include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/thread_identity.h" #include "absl/base/optimization.h" -#include "absl/synchronization/internal/kernel_timeout.h" #include "absl/synchronization/internal/futex.h" +#include "absl/synchronization/internal/kernel_timeout.h" namespace absl { ABSL_NAMESPACE_BEGIN
diff --git a/absl/synchronization/internal/graphcycles.cc b/absl/synchronization/internal/graphcycles.cc index 3f8bb3a..25b51ff 100644 --- a/absl/synchronization/internal/graphcycles.cc +++ b/absl/synchronization/internal/graphcycles.cc
@@ -28,22 +28,25 @@ // (2) When a new edge (x->y) is inserted, do nothing if rank[x] < rank[y]. // (3) Otherwise: adjust ranks in the neighborhood of x and y. -#include <cstddef> -#include <iterator> - -#include "absl/base/attributes.h" +#include "absl/base/internal/low_level_alloc.h" // IWYU pragma: keep // This file is a no-op if the required LowLevelAlloc support is missing. -#include "absl/base/internal/low_level_alloc.h" #ifndef ABSL_LOW_LEVEL_ALLOC_MISSING #include <algorithm> #include <array> #include <cinttypes> +#include <cstddef> +#include <cstdint> #include <limits> +#include "absl/algorithm/container.h" +#include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/base/internal/hide_ptr.h" #include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/scheduling_mode.h" #include "absl/base/internal/spinlock.h" +#include "absl/base/macros.h" #include "absl/synchronization/internal/graphcycles.h" // Do not use STL. This module does not use standard memory allocation. @@ -625,7 +628,7 @@ }; ByRank cmp; cmp.nodes = &nodes; - std::sort(delta->begin(), delta->end(), cmp); + absl::c_sort(*delta, cmp); } static void MoveToList(GraphCycles::Rep* r, Vec<int32_t>* src,
diff --git a/absl/synchronization/internal/graphcycles.h b/absl/synchronization/internal/graphcycles.h index 08f304b..da06504 100644 --- a/absl/synchronization/internal/graphcycles.h +++ b/absl/synchronization/internal/graphcycles.h
@@ -80,20 +80,20 @@ // Attempt to insert an edge from source_node to dest_node. If the // edge would introduce a cycle, return false without making any // changes. Otherwise add the edge and return true. - bool InsertEdge(GraphId source_node, GraphId dest_node); + bool InsertEdge(GraphId idx, GraphId idy); // Remove any edge that exists from source_node to dest_node. - void RemoveEdge(GraphId source_node, GraphId dest_node); + void RemoveEdge(GraphId x, GraphId y); // Return whether node exists in the graph. bool HasNode(GraphId node); // Return whether there is an edge directly from source_node to dest_node. - bool HasEdge(GraphId source_node, GraphId dest_node) const; + bool HasEdge(GraphId x, GraphId y) const; // Return whether dest_node is reachable from source_node // by following edges. - bool IsReachable(GraphId source_node, GraphId dest_node) const; + bool IsReachable(GraphId x, GraphId y) const; // Find a path from "source" to "dest". If such a path exists, // place the nodes on the path in the array path[], and return @@ -107,7 +107,7 @@ // source and destination node if they are identical; therefore, the // return value is at most one greater than the number of nodes in // the graph. - int FindPath(GraphId source, GraphId dest, int max_path_len, + int FindPath(GraphId idx, GraphId idy, int max_path_len, GraphId path[]) const; // Update the stack trace recorded for id with the current stack @@ -143,4 +143,4 @@ ABSL_NAMESPACE_END } // namespace absl -#endif +#endif // ABSL_SYNCHRONIZATION_INTERNAL_GRAPHCYCLES_H_
diff --git a/absl/synchronization/internal/graphcycles_test.cc b/absl/synchronization/internal/graphcycles_test.cc index 4f1a485..9e44a58 100644 --- a/absl/synchronization/internal/graphcycles_test.cc +++ b/absl/synchronization/internal/graphcycles_test.cc
@@ -16,6 +16,7 @@ #include <climits> #include <cstdint> +#include <cstdio> #include <iterator> #include <map> #include <random> @@ -24,7 +25,9 @@ #include <vector> #include "gtest/gtest.h" +#include "absl/base/config.h" #include "absl/base/macros.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/check.h" #include "absl/log/log.h" @@ -51,8 +54,8 @@ } // Return whether "to" is reachable from "from". -static bool IsReachable(Edges *edges, int from, int to, - std::unordered_set<int> *seen) { +static bool IsReachable(Edges* edges, int from, int to, + absl::flat_hash_set<int>* seen) { seen->insert(from); // we are investigating "from"; don't do it again if (from == to) return true; for (const auto &edge : *edges) { @@ -94,7 +97,7 @@ LOG(INFO) << "Transitive closure"; for (int a : *nodes) { for (int b : *nodes) { - std::unordered_set<int> seen; + absl::flat_hash_set<int> seen; if (IsReachable(edges, a, b, &seen)) { LOG(INFO) << a << " " << b; } @@ -118,7 +121,7 @@ static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id, GraphCycles *gc) { - std::unordered_set<int> seen; + absl::flat_hash_set<int> seen; for (const auto &a : *nodes) { for (const auto &b : *nodes) { seen.clear(); @@ -227,7 +230,7 @@ break; case 1: // Remove a node - if (nodes.size() > 0) { + if (!nodes.empty()) { int node_index = RandomNode(&rng, &nodes); int node = nodes[node_index]; nodes[node_index] = nodes.back(); @@ -248,7 +251,7 @@ break; case 2: // Add an edge - if (nodes.size() > 0) { + if (!nodes.empty()) { int from = RandomNode(&rng, &nodes); int to = RandomNode(&rng, &nodes); if (EdgeIndex(&edges, nodes[from], nodes[to]) == -1) { @@ -258,7 +261,7 @@ new_edge.to = nodes[to]; edges.push_back(new_edge); } else { - std::unordered_set<int> seen; + absl::flat_hash_set<int> seen; ASSERT_TRUE(IsReachable(&edges, nodes[to], nodes[from], &seen)) << "Edge " << nodes[to] << "->" << nodes[from]; } @@ -267,7 +270,7 @@ break; case 3: // Remove an edge - if (edges.size() > 0) { + if (!edges.empty()) { int i = RandomEdge(&rng, &edges); int from = edges[i].from; int to = edges[i].to; @@ -280,13 +283,13 @@ break; case 4: // Check a path - if (nodes.size() > 0) { + if (!nodes.empty()) { int from = RandomNode(&rng, &nodes); int to = RandomNode(&rng, &nodes); GraphId path[2*kMaxNodes]; int path_len = graph_cycles.FindPath(id[nodes[from]], id[nodes[to]], std::size(path), path); - std::unordered_set<int> seen; + absl::flat_hash_set<int> seen; bool reachable = IsReachable(&edges, nodes[from], nodes[to], &seen); bool gc_reachable = graph_cycles.IsReachable(Get(id, nodes[from]), Get(id, nodes[to]));
diff --git a/absl/synchronization/internal/kernel_timeout.cc b/absl/synchronization/internal/kernel_timeout.cc index 252397a..cce8bf7 100644 --- a/absl/synchronization/internal/kernel_timeout.cc +++ b/absl/synchronization/internal/kernel_timeout.cc
@@ -21,14 +21,12 @@ #include <algorithm> #include <chrono> // NOLINT(build/c++11) #include <cstdint> -#include <cstdlib> -#include <cstring> #include <ctime> #include <limits> -#include "absl/base/attributes.h" -#include "absl/base/call_once.h" #include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/time/clock.h" #include "absl/time/time.h" namespace absl {
diff --git a/absl/synchronization/internal/kernel_timeout_test.cc b/absl/synchronization/internal/kernel_timeout_test.cc index 811246c..baa2e0f 100644 --- a/absl/synchronization/internal/kernel_timeout_test.cc +++ b/absl/synchronization/internal/kernel_timeout_test.cc
@@ -14,15 +14,14 @@ #include "absl/synchronization/internal/kernel_timeout.h" -#include <ctime> +#include <algorithm> #include <chrono> // NOLINT(build/c++11) +#include <cstdint> #include <limits> -#include "absl/base/config.h" -#include "absl/random/random.h" +#include "gtest/gtest.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "gtest/gtest.h" #if 0 // All supported platforms currently have steady clocks. #define ABSL_INTERNAL_KERNEL_TIMEOUT_SUPPORTS_STEADY_CLOCK 0
diff --git a/absl/synchronization/internal/per_thread_sem.cc b/absl/synchronization/internal/per_thread_sem.cc index c9b8dc1..8ba2a20 100644 --- a/absl/synchronization/internal/per_thread_sem.cc +++ b/absl/synchronization/internal/per_thread_sem.cc
@@ -12,16 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -// This file is a no-op if the required LowLevelAlloc support is missing. -#include "absl/base/internal/low_level_alloc.h" -#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING +#include "absl/base/internal/low_level_alloc.h" // IWYU pragma: keep -#include "absl/synchronization/internal/per_thread_sem.h" +// This file is a no-op if the required LowLevelAlloc support is missing. +#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING #include <atomic> #include "absl/base/attributes.h" +#include "absl/base/config.h" #include "absl/base/internal/thread_identity.h" +#include "absl/synchronization/internal/create_thread_identity.h" +#include "absl/synchronization/internal/kernel_timeout.h" +#include "absl/synchronization/internal/per_thread_sem.h" #include "absl/synchronization/internal/waiter.h" namespace absl {
diff --git a/absl/synchronization/internal/per_thread_sem_test.cc b/absl/synchronization/internal/per_thread_sem_test.cc index 46f903a..4c5ca69 100644 --- a/absl/synchronization/internal/per_thread_sem_test.cc +++ b/absl/synchronization/internal/per_thread_sem_test.cc
@@ -14,19 +14,25 @@ #include "absl/synchronization/internal/per_thread_sem.h" +#include <algorithm> #include <atomic> #include <condition_variable> // NOLINT(build/c++11) +#include <cstdint> +#include <cstdio> #include <functional> #include <limits> -#include <mutex> // NOLINT(build/c++11) +#include <mutex> // NOLINT(build/c++11) #include <string> -#include <thread> // NOLINT(build/c++11) +#include <thread> // NOLINT(build/c++11) #include "gtest/gtest.h" +#include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/internal/cycleclock.h" #include "absl/base/internal/thread_identity.h" #include "absl/strings/str_cat.h" +#include "absl/synchronization/internal/create_thread_identity.h" +#include "absl/synchronization/internal/kernel_timeout.h" #include "absl/time/clock.h" #include "absl/time/time.h"
diff --git a/absl/synchronization/internal/pthread_waiter.cc b/absl/synchronization/internal/pthread_waiter.cc index eead9de..5b27d0f 100644 --- a/absl/synchronization/internal/pthread_waiter.cc +++ b/absl/synchronization/internal/pthread_waiter.cc
@@ -25,7 +25,6 @@ #include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/thread_identity.h" #include "absl/base/optimization.h" #include "absl/synchronization/internal/kernel_timeout.h" @@ -59,12 +58,12 @@ } // namespace PthreadWaiter::PthreadWaiter() : waiter_count_(0), wakeup_count_(0) { - const int err = pthread_mutex_init(&mu_, 0); + const int err = pthread_mutex_init(&mu_, nullptr); if (err != 0) { ABSL_RAW_LOG(FATAL, "pthread_mutex_init failed: %d", err); } - const int err2 = pthread_cond_init(&cv_, 0); + const int err2 = pthread_cond_init(&cv_, nullptr); if (err2 != 0) { ABSL_RAW_LOG(FATAL, "pthread_cond_init failed: %d", err2); }
diff --git a/absl/synchronization/internal/sem_waiter.cc b/absl/synchronization/internal/sem_waiter.cc index 2119290..50f5960 100644 --- a/absl/synchronization/internal/sem_waiter.cc +++ b/absl/synchronization/internal/sem_waiter.cc
@@ -20,13 +20,10 @@ #include <atomic> #include <cassert> -#include <cstdint> #include <cerrno> #include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/thread_identity.h" -#include "absl/base/optimization.h" #include "absl/synchronization/internal/kernel_timeout.h" namespace absl {
diff --git a/absl/synchronization/internal/stdcpp_waiter.cc b/absl/synchronization/internal/stdcpp_waiter.cc index 607d683..c9368d5 100644 --- a/absl/synchronization/internal/stdcpp_waiter.cc +++ b/absl/synchronization/internal/stdcpp_waiter.cc
@@ -16,14 +16,10 @@ #ifdef ABSL_INTERNAL_HAVE_STDCPP_WAITER -#include <chrono> // NOLINT(build/c++11) #include <condition_variable> // NOLINT(build/c++11) #include <mutex> // NOLINT(build/c++11) #include "absl/base/config.h" -#include "absl/base/internal/raw_logging.h" -#include "absl/base/internal/thread_identity.h" -#include "absl/base/optimization.h" #include "absl/synchronization/internal/kernel_timeout.h" namespace absl {
diff --git a/absl/synchronization/internal/waiter_base.cc b/absl/synchronization/internal/waiter_base.cc index e9797f8..011de18 100644 --- a/absl/synchronization/internal/waiter_base.cc +++ b/absl/synchronization/internal/waiter_base.cc
@@ -14,6 +14,9 @@ #include "absl/synchronization/internal/waiter_base.h" +#include <atomic> +#include <cassert> + #include "absl/base/config.h" #include "absl/base/internal/thread_identity.h"
diff --git a/absl/synchronization/internal/waiter_test.cc b/absl/synchronization/internal/waiter_test.cc index 80a6985..44f0d6f 100644 --- a/absl/synchronization/internal/waiter_test.cc +++ b/absl/synchronization/internal/waiter_test.cc
@@ -18,7 +18,7 @@ #include <iostream> #include <ostream> -#include "absl/base/config.h" +#include "gtest/gtest.h" #include "absl/random/random.h" #include "absl/synchronization/internal/create_thread_identity.h" #include "absl/synchronization/internal/futex_waiter.h" @@ -27,10 +27,8 @@ #include "absl/synchronization/internal/sem_waiter.h" #include "absl/synchronization/internal/stdcpp_waiter.h" #include "absl/synchronization/internal/thread_pool.h" -#include "absl/synchronization/internal/win32_waiter.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "gtest/gtest.h" // Test go/btm support by randomizing the value of clock_gettime() for // CLOCK_MONOTONIC. This works by overriding a weak symbol in glibc.
diff --git a/absl/synchronization/lifetime_test.cc b/absl/synchronization/lifetime_test.cc index 1c11431..a659bcf 100644 --- a/absl/synchronization/lifetime_test.cc +++ b/absl/synchronization/lifetime_test.cc
@@ -14,7 +14,6 @@ #include <cstdlib> #include <thread> // NOLINT(build/c++11), Abseil test -#include <type_traits> #include "absl/base/attributes.h" #include "absl/base/const_init.h"
diff --git a/absl/synchronization/mutex.cc b/absl/synchronization/mutex.cc index 63414bb..cb982f6 100644 --- a/absl/synchronization/mutex.cc +++ b/absl/synchronization/mutex.cc
@@ -28,7 +28,6 @@ #endif #include <assert.h> -#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -37,6 +36,7 @@ #include <algorithm> #include <atomic> #include <cstddef> +#include <cstdint> #include <cstdlib> #include <cstring> #include <thread> // NOLINT(build/c++11) @@ -49,16 +49,23 @@ #include "absl/base/internal/cycleclock.h" #include "absl/base/internal/hide_ptr.h" #include "absl/base/internal/low_level_alloc.h" +#include "absl/base/internal/low_level_scheduling.h" #include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/scheduling_mode.h" #include "absl/base/internal/spinlock.h" #include "absl/base/internal/sysinfo.h" #include "absl/base/internal/thread_identity.h" #include "absl/base/internal/tsan_mutex_interface.h" +#include "absl/base/macros.h" #include "absl/base/optimization.h" +#include "absl/base/thread_annotations.h" #include "absl/debugging/stacktrace.h" #include "absl/debugging/symbolize.h" +#include "absl/synchronization/internal/create_thread_identity.h" #include "absl/synchronization/internal/graphcycles.h" +#include "absl/synchronization/internal/kernel_timeout.h" #include "absl/synchronization/internal/per_thread_sem.h" +#include "absl/time/clock.h" #include "absl/time/time.h" using absl::base_internal::CurrentThreadIdentityIfPresent;
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h index 03cce89..b81c595 100644 --- a/absl/synchronization/mutex.h +++ b/absl/synchronization/mutex.h
@@ -964,7 +964,7 @@ // Helper methods for storing, validating, and reading callback arguments. template <typename T> - inline void StoreCallback(T callback) { + void StoreCallback(T callback) { static_assert( sizeof(callback) <= sizeof(callback_), "An overlarge pointer was passed as a callback to Condition."); @@ -972,7 +972,7 @@ } template <typename T> - inline void ReadCallback(T* absl_nonnull callback) const { + void ReadCallback(T* absl_nonnull callback) const { std::memcpy(callback, callback_, sizeof(*callback)); } @@ -1188,7 +1188,7 @@ ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); } -inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {} +constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {} #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) ABSL_ATTRIBUTE_ALWAYS_INLINE
diff --git a/absl/synchronization/mutex_benchmark.cc b/absl/synchronization/mutex_benchmark.cc index d2c6495..2df1d67 100644 --- a/absl/synchronization/mutex_benchmark.cc +++ b/absl/synchronization/mutex_benchmark.cc
@@ -12,15 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include <atomic> #include <cstdint> +#include <limits> #include <mutex> // NOLINT(build/c++11) #include <vector> -#include "absl/base/config.h" #include "absl/base/internal/cycleclock.h" +#include "absl/base/internal/raw_logging.h" #include "absl/base/internal/spinlock.h" +#include "absl/base/internal/thread_identity.h" #include "absl/base/no_destructor.h" #include "absl/synchronization/blocking_counter.h" +#include "absl/synchronization/internal/create_thread_identity.h" +#include "absl/synchronization/internal/per_thread_sem.h" #include "absl/synchronization/internal/thread_pool.h" #include "absl/synchronization/mutex.h" #include "benchmark/benchmark.h" @@ -30,7 +35,7 @@ void BM_Mutex(benchmark::State& state) { static absl::NoDestructor<absl::Mutex> mu; for (auto _ : state) { - absl::MutexLock lock(*mu.get()); + absl::MutexLock lock(*mu); } } BENCHMARK(BM_Mutex)->UseRealTime()->Threads(1)->ThreadPerCpu(); @@ -38,7 +43,7 @@ void BM_ReaderLock(benchmark::State& state) { static absl::NoDestructor<absl::Mutex> mu; for (auto _ : state) { - absl::ReaderMutexLock lock(*mu.get()); + absl::ReaderMutexLock lock(*mu); } } BENCHMARK(BM_ReaderLock)->UseRealTime()->Threads(1)->ThreadPerCpu();
diff --git a/absl/synchronization/mutex_method_pointer_test.cc b/absl/synchronization/mutex_method_pointer_test.cc index f4c82d2..420750b 100644 --- a/absl/synchronization/mutex_method_pointer_test.cc +++ b/absl/synchronization/mutex_method_pointer_test.cc
@@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "absl/synchronization/mutex.h" - -#include <cstdlib> #include <string> #include "gtest/gtest.h" -#include "absl/base/config.h" + +#ifdef _MSC_VER +#include "absl/synchronization/mutex.h" +#endif namespace {
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc index 5663cf6..42e5eb9 100644 --- a/absl/synchronization/mutex_test.cc +++ b/absl/synchronization/mutex_test.cc
@@ -24,6 +24,7 @@ #include <functional> #include <memory> #include <mutex> // NOLINT(build/c++11) +#include <ostream> #include <random> #include <shared_mutex> // NOLINT(build/c++14) #include <string> @@ -32,12 +33,10 @@ #include <vector> #include "gtest/gtest.h" -#include "absl/base/attributes.h" #include "absl/base/config.h" -#include "absl/base/internal/sysinfo.h" +#include "absl/base/thread_annotations.h" #include "absl/log/check.h" #include "absl/log/log.h" -#include "absl/memory/memory.h" #include "absl/random/random.h" #include "absl/synchronization/internal/create_thread_identity.h" #include "absl/synchronization/internal/thread_pool.h"
diff --git a/absl/synchronization/notification.cc b/absl/synchronization/notification.cc index a890c1b..63da068 100644 --- a/absl/synchronization/notification.cc +++ b/absl/synchronization/notification.cc
@@ -16,8 +16,10 @@ #include <atomic> +#include "absl/base/config.h" #include "absl/base/internal/raw_logging.h" #include "absl/base/internal/tracing.h" +#include "absl/base/optimization.h" #include "absl/synchronization/mutex.h" #include "absl/time/time.h"
diff --git a/absl/synchronization/notification.h b/absl/synchronization/notification.h index 12df31b..420b820 100644 --- a/absl/synchronization/notification.h +++ b/absl/synchronization/notification.h
@@ -114,12 +114,11 @@ private: // Convenience helper to reduce verbosity at call sites. - static inline constexpr base_internal::ObjectKind TraceObjectKind() { + static constexpr base_internal::ObjectKind TraceObjectKind() { return base_internal::ObjectKind::kNotification; } - static inline bool HasBeenNotifiedInternal( - const std::atomic<bool>* notified_yet) { + static bool HasBeenNotifiedInternal(const std::atomic<bool>* notified_yet) { return notified_yet->load(std::memory_order_acquire); }
diff --git a/absl/synchronization/notification_test.cc b/absl/synchronization/notification_test.cc index ac5dccd..ded80a5 100644 --- a/absl/synchronization/notification_test.cc +++ b/absl/synchronization/notification_test.cc
@@ -23,6 +23,7 @@ #include "absl/base/config.h" #include "absl/base/internal/tracing.h" #include "absl/synchronization/mutex.h" +#include "absl/time/clock.h" #include "absl/time/time.h" namespace absl {
diff --git a/absl/time/civil_time_test.cc b/absl/time/civil_time_test.cc index f6d1682..fed0c30 100644 --- a/absl/time/civil_time_test.cc +++ b/absl/time/civil_time_test.cc
@@ -296,33 +296,33 @@ TEST(CivilTime, DisallowCrossAlignedDifference) { // Difference is allowed between types with the same alignment. - static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value, ""); - static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value, ""); - static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value, ""); - static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value, ""); - static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value, ""); - static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value, ""); + static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value); + static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value); + static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value); + static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value); + static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value); + static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value); // Difference is disallowed between types with different alignments. - static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value, ""); - static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value, ""); - static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value, ""); - static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value, ""); - static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value, ""); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value); + static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value); - static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value, ""); - static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value, ""); - static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value, ""); - static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value, ""); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value); + static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value); - static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value, ""); - static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value, ""); - static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value, ""); + static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value); + static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value); + static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value); - static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value, ""); - static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value, ""); + static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value); + static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value); - static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value, ""); + static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value); } TEST(CivilTime, ValueSemantics) {
diff --git a/absl/time/duration.cc b/absl/time/duration.cc index fb7c90a..ec92206 100644 --- a/absl/time/duration.cc +++ b/absl/time/duration.cc
@@ -834,7 +834,7 @@ default: break; } - ABSL_FALLTHROUGH_INTENDED; + [[fallthrough]]; case 1: switch (**start) { case 's':
diff --git a/absl/time/duration_test.cc b/absl/time/duration_test.cc index f56df40..d265dbf 100644 --- a/absl/time/duration_test.cc +++ b/absl/time/duration_test.cc
@@ -228,12 +228,12 @@ 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)), ""); - static_assert(absl::Milliseconds(N) == absl::FromChrono(milliseconds(N)), ""); - static_assert(absl::Seconds(N) == absl::FromChrono(seconds(N)), ""); - static_assert(absl::Minutes(N) == absl::FromChrono(minutes(N)), ""); - static_assert(absl::Hours(N) == absl::FromChrono(hours(N)), ""); + static_assert(absl::Nanoseconds(N) == absl::FromChrono(nanoseconds(N))); + static_assert(absl::Microseconds(N) == absl::FromChrono(microseconds(N))); + static_assert(absl::Milliseconds(N) == absl::FromChrono(milliseconds(N))); + static_assert(absl::Seconds(N) == absl::FromChrono(seconds(N))); + static_assert(absl::Minutes(N) == absl::FromChrono(minutes(N))); + static_assert(absl::Hours(N) == absl::FromChrono(hours(N))); } TEST(Duration, FromChrono) { @@ -907,15 +907,15 @@ } TEST(Duration, RelationalOperators) { -#define TEST_REL_OPS(UNIT) \ - static_assert(UNIT(2) == UNIT(2), ""); \ - static_assert(UNIT(1) != UNIT(2), ""); \ - static_assert(UNIT(1) < UNIT(2), ""); \ - static_assert(UNIT(3) > UNIT(2), ""); \ - static_assert(UNIT(1) <= UNIT(2), ""); \ - static_assert(UNIT(2) <= UNIT(2), ""); \ - static_assert(UNIT(3) >= UNIT(2), ""); \ - static_assert(UNIT(2) >= UNIT(2), ""); +#define TEST_REL_OPS(UNIT) \ + static_assert(UNIT(2) == UNIT(2)); \ + static_assert(UNIT(1) != UNIT(2)); \ + static_assert(UNIT(1) < UNIT(2)); \ + static_assert(UNIT(3) > UNIT(2)); \ + static_assert(UNIT(1) <= UNIT(2)); \ + static_assert(UNIT(2) <= UNIT(2)); \ + static_assert(UNIT(3) >= UNIT(2)); \ + static_assert(UNIT(2) >= UNIT(2)); TEST_REL_OPS(absl::Nanoseconds); TEST_REL_OPS(absl::Microseconds); @@ -930,10 +930,10 @@ #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON TEST(Duration, SpaceshipOperators) { -#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(3) <=> UNIT(2) == std::strong_ordering::greater, ""); +#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(3) <=> UNIT(2) == std::strong_ordering::greater); TEST_REL_OPS(absl::Nanoseconds); TEST_REL_OPS(absl::Microseconds);
diff --git a/absl/time/time_test.cc b/absl/time/time_test.cc index 35b1f0e..49f6dd6 100644 --- a/absl/time/time_test.cc +++ b/absl/time/time_test.cc
@@ -194,46 +194,46 @@ constexpr absl::Time t2 = absl::FromUnixNanos(1); constexpr absl::Time t3 = absl::FromUnixNanos(2); - static_assert(absl::UnixEpoch() == t1, ""); - static_assert(t1 == t1, ""); - static_assert(t2 == t2, ""); - static_assert(t3 == t3, ""); + static_assert(absl::UnixEpoch() == t1); + static_assert(t1 == t1); + static_assert(t2 == t2); + static_assert(t3 == t3); - static_assert(t1 < t2, ""); - static_assert(t2 < t3, ""); - static_assert(t1 < t3, ""); + static_assert(t1 < t2); + static_assert(t2 < t3); + static_assert(t1 < t3); - static_assert(t1 <= t1, ""); - static_assert(t1 <= t2, ""); - static_assert(t2 <= t2, ""); - static_assert(t2 <= t3, ""); - static_assert(t3 <= t3, ""); - static_assert(t1 <= t3, ""); + static_assert(t1 <= t1); + static_assert(t1 <= t2); + static_assert(t2 <= t2); + static_assert(t2 <= t3); + static_assert(t3 <= t3); + static_assert(t1 <= t3); - static_assert(t2 > t1, ""); - static_assert(t3 > t2, ""); - static_assert(t3 > t1, ""); + static_assert(t2 > t1); + static_assert(t3 > t2); + static_assert(t3 > t1); - static_assert(t2 >= t2, ""); - static_assert(t2 >= t1, ""); - static_assert(t3 >= t3, ""); - static_assert(t3 >= t2, ""); - static_assert(t1 >= t1, ""); - static_assert(t3 >= t1, ""); + static_assert(t2 >= t2); + static_assert(t2 >= t1); + static_assert(t3 >= t3); + static_assert(t3 >= t2); + static_assert(t1 >= t1); + static_assert(t3 >= t1); #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON - static_assert((t1 <=> t1) == std::strong_ordering::equal, ""); - static_assert((t2 <=> t2) == std::strong_ordering::equal, ""); - static_assert((t3 <=> t3) == std::strong_ordering::equal, ""); + static_assert((t1 <=> t1) == std::strong_ordering::equal); + static_assert((t2 <=> t2) == std::strong_ordering::equal); + static_assert((t3 <=> t3) == std::strong_ordering::equal); - static_assert((t1 <=> t2) == std::strong_ordering::less, ""); - static_assert((t2 <=> t3) == std::strong_ordering::less, ""); - static_assert((t1 <=> t3) == std::strong_ordering::less, ""); + static_assert((t1 <=> t2) == std::strong_ordering::less); + static_assert((t2 <=> t3) == std::strong_ordering::less); + static_assert((t1 <=> t3) == std::strong_ordering::less); - static_assert((t2 <=> t1) == std::strong_ordering::greater, ""); - static_assert((t3 <=> t2) == std::strong_ordering::greater, ""); - static_assert((t3 <=> t1) == std::strong_ordering::greater, ""); + static_assert((t2 <=> t1) == std::strong_ordering::greater); + static_assert((t3 <=> t2) == std::strong_ordering::greater); + static_assert((t3 <=> t1) == std::strong_ordering::greater); #endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON } @@ -242,17 +242,17 @@ constexpr absl::Time ifuture = absl::InfiniteFuture(); constexpr absl::Time ipast = absl::InfinitePast(); - static_assert(ifuture == ifuture, ""); - static_assert(ipast == ipast, ""); - static_assert(ipast < ifuture, ""); - static_assert(ifuture > ipast, ""); + static_assert(ifuture == ifuture); + static_assert(ipast == ipast); + static_assert(ipast < ifuture); + static_assert(ifuture > ipast); #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON - static_assert((ifuture <=> ifuture) == std::strong_ordering::equal, ""); - static_assert((ipast <=> ipast) == std::strong_ordering::equal, ""); - static_assert((ipast <=> ifuture) == std::strong_ordering::less, ""); - static_assert((ifuture <=> ipast) == std::strong_ordering::greater, ""); + static_assert((ifuture <=> ifuture) == std::strong_ordering::equal); + static_assert((ipast <=> ipast) == std::strong_ordering::equal); + static_assert((ipast <=> ifuture) == std::strong_ordering::less); + static_assert((ifuture <=> ipast) == std::strong_ordering::greater); #endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON @@ -268,15 +268,15 @@ EXPECT_EQ(-absl::InfiniteDuration(), ipast - ipast); constexpr absl::Time t = absl::UnixEpoch(); // Any finite time. - static_assert(t < ifuture, ""); - static_assert(t > ipast, ""); + static_assert(t < ifuture); + static_assert(t > ipast); #ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON - static_assert((t <=> ifuture) == std::strong_ordering::less, ""); - static_assert((t <=> ipast) == std::strong_ordering::greater, ""); - static_assert((ipast <=> t) == std::strong_ordering::less, ""); - static_assert((ifuture <=> t) == std::strong_ordering::greater, ""); + static_assert((t <=> ifuture) == std::strong_ordering::less); + static_assert((t <=> ipast) == std::strong_ordering::greater); + static_assert((ipast <=> t) == std::strong_ordering::less); + static_assert((ifuture <=> t) == std::strong_ordering::greater); #endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
diff --git a/absl/types/any_span.h b/absl/types/any_span.h index 04e64dc..5c85892 100644 --- a/absl/types/any_span.h +++ b/absl/types/any_span.h
@@ -390,7 +390,7 @@ using difference_type = std::ptrdiff_t; using absl_internal_is_view = std::true_type; - static const size_type npos = static_cast<size_type>(-1); // NOLINT + static constexpr size_type npos = static_cast<size_type>(-1); // NOLINT using reference = T&; using const_reference = std::add_const_t<T>&; @@ -893,9 +893,6 @@ // Implementation details follow. // -template <typename T> -const typename AnySpan<T>::size_type AnySpan<T>::npos; - // Iterator base class. Uses CRTP (Iter should be the child class). Constness of // the iterator is determined by the constness of Value. template <typename T>
diff --git a/absl/types/compare.h b/absl/types/compare.h index be59d92..e6a2a57 100644 --- a/absl/types/compare.h +++ b/absl/types/compare.h
@@ -23,7 +23,7 @@ // Example: // absl::weak_ordering compare(const std::string& a, const std::string& b); // -// These are C++11 compatible versions of the C++20 corresponding types +// These are C++17 compatible versions of the C++20 corresponding types // (`std::partial_ordering`, etc.) and are designed to be drop-in replacements // for code compliant with C++20. @@ -110,71 +110,15 @@ enum class ncmp : value_type { unordered = -127 }; -// Define macros to allow for creation or emulation of C++17 inline variables -// based on whether the feature is supported. Note: we can't use -// ABSL_INTERNAL_INLINE_CONSTEXPR here because the variables here are of -// incomplete types so they need to be defined after the types are complete. -#ifdef __cpp_inline_variables - -// A no-op expansion that can be followed by a semicolon at class level. -#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) static_assert(true, "") - -#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static const type name - -#define ABSL_COMPARE_INLINE_INIT(type, name, init) \ - inline constexpr type type::name(init) - -#else // __cpp_inline_variables - -#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \ - ABSL_CONST_INIT static const T name - -// A no-op expansion that can be followed by a semicolon at class level. -#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static_assert(true, "") - -#define ABSL_COMPARE_INLINE_INIT(type, name, init) \ - template <typename T> \ - const T compare_internal::type##_base<T>::name(init) - -#endif // __cpp_inline_variables - -// These template base classes allow for defining the values of the constants -// in the header file (for performance) without using inline variables (which -// aren't available in C++11). -template <typename T> -struct partial_ordering_base { - ABSL_COMPARE_INLINE_BASECLASS_DECL(less); - ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); - ABSL_COMPARE_INLINE_BASECLASS_DECL(greater); - ABSL_COMPARE_INLINE_BASECLASS_DECL(unordered); -}; - -template <typename T> -struct weak_ordering_base { - ABSL_COMPARE_INLINE_BASECLASS_DECL(less); - ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); - ABSL_COMPARE_INLINE_BASECLASS_DECL(greater); -}; - -template <typename T> -struct strong_ordering_base { - ABSL_COMPARE_INLINE_BASECLASS_DECL(less); - ABSL_COMPARE_INLINE_BASECLASS_DECL(equal); - ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent); - ABSL_COMPARE_INLINE_BASECLASS_DECL(greater); -}; - } // namespace compare_internal -class partial_ordering - : public compare_internal::partial_ordering_base<partial_ordering> { +class partial_ordering { explicit constexpr partial_ordering(compare_internal::eq v) noexcept : value_(static_cast<compare_internal::value_type>(v)) {} explicit constexpr partial_ordering(compare_internal::ord v) noexcept : value_(static_cast<compare_internal::value_type>(v)) {} explicit constexpr partial_ordering(compare_internal::ncmp v) noexcept : value_(static_cast<compare_internal::value_type>(v)) {} - friend struct compare_internal::partial_ordering_base<partial_ordering>; constexpr bool is_ordered() const noexcept { return value_ != @@ -182,10 +126,10 @@ } public: - ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, less); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, equivalent); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered); + static const partial_ordering less; + static const partial_ordering equivalent; + static const partial_ordering greater; + static const partial_ordering unordered; // Comparisons friend constexpr bool operator==(partial_ordering v, @@ -248,26 +192,25 @@ private: compare_internal::value_type value_; }; -ABSL_COMPARE_INLINE_INIT(partial_ordering, less, compare_internal::ord::less); -ABSL_COMPARE_INLINE_INIT(partial_ordering, equivalent, - compare_internal::eq::equivalent); -ABSL_COMPARE_INLINE_INIT(partial_ordering, greater, - compare_internal::ord::greater); -ABSL_COMPARE_INLINE_INIT(partial_ordering, unordered, - compare_internal::ncmp::unordered); +inline constexpr partial_ordering partial_ordering::less( + compare_internal::ord::less); +inline constexpr partial_ordering partial_ordering::equivalent( + compare_internal::eq::equivalent); +inline constexpr partial_ordering partial_ordering::greater( + compare_internal::ord::greater); +inline constexpr partial_ordering partial_ordering::unordered( + compare_internal::ncmp::unordered); -class weak_ordering - : public compare_internal::weak_ordering_base<weak_ordering> { +class weak_ordering { explicit constexpr weak_ordering(compare_internal::eq v) noexcept : value_(static_cast<compare_internal::value_type>(v)) {} explicit constexpr weak_ordering(compare_internal::ord v) noexcept : value_(static_cast<compare_internal::value_type>(v)) {} - friend struct compare_internal::weak_ordering_base<weak_ordering>; public: - ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, less); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, equivalent); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater); + static const weak_ordering less; + static const weak_ordering equivalent; + static const weak_ordering greater; // Conversions constexpr operator partial_ordering() const noexcept { // NOLINT @@ -336,25 +279,23 @@ private: compare_internal::value_type value_; }; -ABSL_COMPARE_INLINE_INIT(weak_ordering, less, compare_internal::ord::less); -ABSL_COMPARE_INLINE_INIT(weak_ordering, equivalent, - compare_internal::eq::equivalent); -ABSL_COMPARE_INLINE_INIT(weak_ordering, greater, - compare_internal::ord::greater); +inline constexpr weak_ordering weak_ordering::less(compare_internal::ord::less); +inline constexpr weak_ordering weak_ordering::equivalent( + compare_internal::eq::equivalent); +inline constexpr weak_ordering weak_ordering::greater( + compare_internal::ord::greater); -class strong_ordering - : public compare_internal::strong_ordering_base<strong_ordering> { +class strong_ordering { explicit constexpr strong_ordering(compare_internal::eq v) noexcept : value_(static_cast<compare_internal::value_type>(v)) {} explicit constexpr strong_ordering(compare_internal::ord v) noexcept : value_(static_cast<compare_internal::value_type>(v)) {} - friend struct compare_internal::strong_ordering_base<strong_ordering>; public: - ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, less); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equal); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equivalent); - ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater); + static const strong_ordering less; + static const strong_ordering equal; + static const strong_ordering equivalent; + static const strong_ordering greater; // Conversions constexpr operator partial_ordering() const noexcept { // NOLINT @@ -428,16 +369,14 @@ private: compare_internal::value_type value_; }; -ABSL_COMPARE_INLINE_INIT(strong_ordering, less, compare_internal::ord::less); -ABSL_COMPARE_INLINE_INIT(strong_ordering, equal, compare_internal::eq::equal); -ABSL_COMPARE_INLINE_INIT(strong_ordering, equivalent, - compare_internal::eq::equivalent); -ABSL_COMPARE_INLINE_INIT(strong_ordering, greater, - compare_internal::ord::greater); - -#undef ABSL_COMPARE_INLINE_BASECLASS_DECL -#undef ABSL_COMPARE_INLINE_SUBCLASS_DECL -#undef ABSL_COMPARE_INLINE_INIT +inline constexpr strong_ordering strong_ordering::less( + compare_internal::ord::less); +inline constexpr strong_ordering strong_ordering::equal( + compare_internal::eq::equal); +inline constexpr strong_ordering strong_ordering::equivalent( + compare_internal::eq::equivalent); +inline constexpr strong_ordering strong_ordering::greater( + compare_internal::ord::greater); #endif // ABSL_USES_STD_ORDERING @@ -479,7 +418,8 @@ template < typename Compare, typename K, typename LK, std::enable_if_t< - !std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>, + !std::is_same_v<bool, + std::invoke_result_t<Compare, const K&, const LK&>>, int> = 0> constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare, const K& x, const LK& y) { @@ -488,7 +428,8 @@ template < typename Compare, typename K, typename LK, std::enable_if_t< - std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>, + std::is_same_v<bool, + std::invoke_result_t<Compare, const K&, const LK&>>, int> = 0> constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare, const K& x, const LK& y) {
diff --git a/absl/types/compare_test.cc b/absl/types/compare_test.cc index 352c9f1..ae73eca 100644 --- a/absl/types/compare_test.cc +++ b/absl/types/compare_test.cc
@@ -277,23 +277,21 @@ absl::compare_internal::do_three_way_comparison(weak, 10, 5) > 0)); } -#ifdef __cpp_inline_variables TEST(Compare, StaticAsserts) { - static_assert(partial_ordering::less < 0, ""); - static_assert(partial_ordering::equivalent == 0, ""); - static_assert(partial_ordering::greater > 0, ""); - static_assert(partial_ordering::unordered != 0, ""); + static_assert(partial_ordering::less < 0); + static_assert(partial_ordering::equivalent == 0); + static_assert(partial_ordering::greater > 0); + static_assert(partial_ordering::unordered != 0); - static_assert(weak_ordering::less < 0, ""); - static_assert(weak_ordering::equivalent == 0, ""); - static_assert(weak_ordering::greater > 0, ""); + static_assert(weak_ordering::less < 0); + static_assert(weak_ordering::equivalent == 0); + static_assert(weak_ordering::greater > 0); - static_assert(strong_ordering::less < 0, ""); - static_assert(strong_ordering::equal == 0, ""); - static_assert(strong_ordering::equivalent == 0, ""); - static_assert(strong_ordering::greater > 0, ""); + static_assert(strong_ordering::less < 0); + static_assert(strong_ordering::equal == 0); + static_assert(strong_ordering::equivalent == 0); + static_assert(strong_ordering::greater > 0); } -#endif // __cpp_inline_variables } // namespace ABSL_NAMESPACE_END
diff --git a/absl/types/internal/any_span.h b/absl/types/internal/any_span.h index ea85a44..00ee742 100644 --- a/absl/types/internal/any_span.h +++ b/absl/types/internal/any_span.h
@@ -465,7 +465,7 @@ template <typename T> bool EqualImpl(AnySpan<T> a, AnySpan<T> b) { - static_assert(std::is_const_v<T>, ""); + static_assert(std::is_const_v<T>); return std::equal(a.begin(), a.end(), b.begin(), b.end()); }
diff --git a/absl/types/internal/span.h b/absl/types/internal/span.h index 148c957..f0f1af6 100644 --- a/absl/types/internal/span.h +++ b/absl/types/internal/span.h
@@ -39,12 +39,6 @@ return c.data(); } -// Before C++17, std::string::data returns a const char* in all cases. -inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references) - int) noexcept { - return &s[0]; -} - template <typename C> constexpr auto GetData(C& c) noexcept // NOLINT(runtime/references) -> decltype(GetDataImpl(c, 0)) { @@ -86,7 +80,7 @@ template <template <typename> class SpanT, typename T> constexpr bool EqualImpl(SpanT<T> a, SpanT<T> b) { - static_assert(std::is_const_v<T>, ""); + static_assert(std::is_const_v<T>); return std::equal(a.begin(), a.end(), b.begin(), b.end()); } @@ -94,7 +88,7 @@ constexpr bool LessThanImpl(SpanT<T> a, SpanT<T> b) { // We can't use value_type since that is remove_cv_t<T>, so we go the long way // around. - static_assert(std::is_const_v<T>, ""); + static_assert(std::is_const_v<T>); return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); }
diff --git a/absl/types/optional_ref_test.cc b/absl/types/optional_ref_test.cc index dda1624..c6f2e76 100644 --- a/absl/types/optional_ref_test.cc +++ b/absl/types/optional_ref_test.cc
@@ -362,7 +362,7 @@ TEST(OptionalRefTest, Constexpr) { static constexpr int foo = 123; constexpr optional_ref<const int> ref(foo); - static_assert(ref.has_value() && *ref == foo && ref.value() == foo, ""); + static_assert(ref.has_value() && *ref == foo && ref.value() == foo); } } // namespace
diff --git a/absl/types/span.h b/absl/types/span.h index c33e294..41aba0a 100644 --- a/absl/types/span.h +++ b/absl/types/span.h
@@ -39,8 +39,7 @@ // * bounds-checked access to `absl::Span` is accomplished with `at()` // however `std::span` now supports the same as of the draft C++26 standard // * `absl::Span` has compiler-provided move and copy constructors and -// assignment. This is due to them being specified as `constexpr`, but that -// implies const in C++11. +// assignment. // * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or // `as_writable_bytes()` methods // * `absl::Span` has no static extent template parameter, nor constructors @@ -85,9 +84,6 @@ // If std::ranges is available, mark Span as satisfying the `view` and // `borrowed_range` concepts, just like std::span. -#if !defined(__has_include) -#define __has_include(header) 0 -#endif #if __has_include(<version>) #include <version> // NOLINT(misc-include-cleaner) #endif @@ -220,7 +216,7 @@ using absl_internal_is_view = std::true_type; // NOLINTNEXTLINE - static const size_type npos = ~(size_type(0)); + static constexpr size_type npos = static_cast<size_type>(-1); constexpr Span() noexcept : Span(nullptr, 0) {} constexpr Span(pointer array ABSL_ATTRIBUTE_LIFETIME_BOUND, @@ -510,9 +506,6 @@ size_type len_; }; -template <typename T> -const typename Span<T>::size_type Span<T>::npos; - // Span relationals // Equality is compared element-by-element, while ordering is lexicographical.
diff --git a/ci/cmake_common.sh b/ci/cmake_common.sh index 53d3a37..1804e14 100644 --- a/ci/cmake_common.sh +++ b/ci/cmake_common.sh
@@ -14,6 +14,6 @@ # The commit of GoogleTest to be used in the CMake tests in this directory. # Keep this in sync with the commit in the MODULE.bazel file. -readonly ABSL_GOOGLETEST_VERSION="1.17.0" +readonly ABSL_GOOGLETEST_VERSION="1.18.0" ABSL_GOOGLETEST_DOWNLOAD_URL="https://github.com/google/googletest/releases/download/v${ABSL_GOOGLETEST_VERSION}/googletest-${ABSL_GOOGLETEST_VERSION}.tar.gz"
diff --git a/ci/windows_msvc_bazel.bat b/ci/windows_msvc_bazel.bat index 031d08f..a4bd3d7 100755 --- a/ci/windows_msvc_bazel.bat +++ b/ci/windows_msvc_bazel.bat
@@ -46,7 +46,7 @@ test ... ^ --compilation_mode=%COMPILATION_MODE% ^ --copt=/WX ^ - --copt=/std:%STD% ^ + --cxxopt=/std:%STD% ^ --define=absl=1 ^ --enable_bzlmod=true ^ --keep_going ^
diff --git a/ci/windows_msvc_cmake.bat b/ci/windows_msvc_cmake.bat index c0083a1..6fbc324 100755 --- a/ci/windows_msvc_cmake.bat +++ b/ci/windows_msvc_cmake.bat
@@ -15,8 +15,8 @@ SETLOCAL ENABLEDELAYEDEXPANSION :: The version of GoogleTest to be used in the CMake tests in this directory. -:: Keep this in sync with the version in the WORKSPACE file. -SET ABSL_GOOGLETEST_VERSION=1.17.0 +:: Keep this in sync with the version in the MODULE.bazel file. +SET ABSL_GOOGLETEST_VERSION=1.18.0 IF EXIST %KOKORO_GFILE_DIR%\distdir\googletest-%ABSL_GOOGLETEST_VERSION%.tar.gz ( SET ABSL_GOOGLETEST_DOWNLOAD_URL=file://%KOKORO_GFILE_DIR%\distdir\googletest-%ABSL_GOOGLETEST_VERSION%.tar.gz