Inline and remove AddConstRefIfExpensive PiperOrigin-RevId: 1008330701
diff --git a/absl/container/internal/raw_hash_map.h b/absl/container/internal/raw_hash_map.h index d4a7564..3495905 100644 --- a/absl/container/internal/raw_hash_map.h +++ b/absl/container/internal/raw_hash_map.h
@@ -382,7 +382,7 @@ // Try to avoid using std::tuple since that slows compilation. // (example: https://godbolt.org/z/nefW93T6K) - if constexpr (type_traits_internal::ShouldPreferPassByValue< + if constexpr (type_traits_internal::ShouldPreferPassByValueOverRRef< std::conditional_t< sizeof...(Args) == 0 && std::is_same_v<
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index 3a5a1ca..06911c5 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h
@@ -2406,19 +2406,14 @@ // This is a 'struct' instead of 'using' in order to avoid eager evaluation for // callers that may be passing incomplete types. -template <class T> -struct AddConstRefIfExpensive - : std::conditional<type_traits_internal::ShouldPreferPassByValue<T>::value, - T, const T&> { - static_assert(std::is_same_v<remove_cvref_t<T>, T>, - "passed types must be unqualified"); -}; - template <class T, class Alloc = std::allocator<T>> -using PreferredParamType = - typename std::conditional_t<IsAllocMoveSameAsCopy<T, Alloc>::value, - AddConstRefIfExpensive<T>, - std::add_rvalue_reference<T>>::type; +struct PreferredParamType + : std::conditional_t< + IsAllocMoveSameAsCopy<T, Alloc>::value, + std::conditional_t< + type_traits_internal::ShouldPreferPassByValueOverRRef<T>::value, + type_identity<T>, std::add_lvalue_reference<std::add_const_t<T>>>, + std::add_rvalue_reference<T>> {}; // A SwissTable. //
diff --git a/absl/meta/type_traits.h b/absl/meta/type_traits.h index 143d14e..ea6db64 100644 --- a/absl/meta/type_traits.h +++ b/absl/meta/type_traits.h
@@ -35,6 +35,8 @@ #ifndef ABSL_META_TYPE_TRAITS_H_ #define ABSL_META_TYPE_TRAITS_H_ +#include <limits.h> + #include <array> #include <cstddef> #include <functional> @@ -645,20 +647,15 @@ alignof(T) * 2 >= sizeof(T) && sizeof(T) <= sizeof(std::pair<void*, size_t>)>; -template <class T> -using ShouldSemanticallyPreferPassByValue = - std::bool_constant<std::is_trivially_move_constructible_v<T> && - std::is_trivially_destructible_v<T>>; - // Checks the given type to see if it is a good candidate for accepting by value // instead of by rvalue-reference. This includes both a semantic constraint // (to ensure correctness), as well as a structural constraint (to ensure // performance). template <class T> -using ShouldPreferPassByValue = - std::bool_constant<ShouldSemanticallyPreferPassByValue<T>::value && - ShouldStructurallyPreferPassByValue<std::conditional_t< - std::is_void_v<T>, char, T>>::value>; +using ShouldPreferPassByValueOverRRef = ShouldStructurallyPreferPassByValue< + std::conditional_t<std::is_trivially_move_constructible_v<T> && + std::is_trivially_destructible_v<T>, + T, char[UINT_MAX]>>; } // namespace type_traits_internal
diff --git a/absl/meta/type_traits_test.cc b/absl/meta/type_traits_test.cc index ff44922..9543861 100644 --- a/absl/meta/type_traits_test.cc +++ b/absl/meta/type_traits_test.cc
@@ -492,22 +492,24 @@ TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {} // NOLINT }; -TEST(ShouldPreferPassByValue, Basic) { - static_assert(ShouldPreferPassByValue<int>::value); - static_assert(ShouldPreferPassByValue<void*>::value); - static_assert(ShouldPreferPassByValue<UnscopedEnum>::value); - static_assert(ShouldPreferPassByValue<ScopedEnum>::value); - static_assert(ShouldPreferPassByValue<TrivialUnion>::value); - static_assert(ShouldPreferPassByValue<std::string_view>::value); - static_assert(ShouldPreferPassByValue<std::pair<int, int>>::value); - static_assert(ShouldPreferPassByValue<std::pair<char, int>>::value); - static_assert(ShouldPreferPassByValue<TrivialMoveNonTrivialCopy>::value); - static_assert(!ShouldPreferPassByValue<TrivialCopyNonTrivialMove>::value); - static_assert(!ShouldPreferPassByValue<void>::value); - static_assert(!ShouldPreferPassByValue<char[3]>::value); - static_assert(!ShouldPreferPassByValue<char[4]>::value); - static_assert(!ShouldPreferPassByValue<std::string>::value); - static_assert(!ShouldPreferPassByValue<std::shared_ptr<int>>::value); +TEST(ShouldPreferPassByValueOverRRef, Basic) { + static_assert(ShouldPreferPassByValueOverRRef<int>::value); + static_assert(ShouldPreferPassByValueOverRRef<void*>::value); + static_assert(ShouldPreferPassByValueOverRRef<UnscopedEnum>::value); + static_assert(ShouldPreferPassByValueOverRRef<ScopedEnum>::value); + static_assert(ShouldPreferPassByValueOverRRef<TrivialUnion>::value); + static_assert(ShouldPreferPassByValueOverRRef<std::string_view>::value); + static_assert(ShouldPreferPassByValueOverRRef<std::pair<int, int>>::value); + static_assert(ShouldPreferPassByValueOverRRef<std::pair<char, int>>::value); + static_assert( + ShouldPreferPassByValueOverRRef<TrivialMoveNonTrivialCopy>::value); + static_assert( + !ShouldPreferPassByValueOverRRef<TrivialCopyNonTrivialMove>::value); + static_assert(!ShouldPreferPassByValueOverRRef<void>::value); + static_assert(!ShouldPreferPassByValueOverRRef<char[3]>::value); + static_assert(!ShouldPreferPassByValueOverRRef<char[4]>::value); + static_assert(!ShouldPreferPassByValueOverRRef<std::string>::value); + static_assert(!ShouldPreferPassByValueOverRRef<std::shared_ptr<int>>::value); } } // namespace