Commit dc44b95a by Abseil Team Committed by Copybara-Service

Support lvalue references to incomplete types as `FunctionRef` parameters.

PiperOrigin-RevId: 514451518
Change-Id: Ic1391374c7bff08ba437ac0410631d1f701bb9ed
parent 807763a7
...@@ -253,6 +253,16 @@ TEST(FunctionRef, PassByValueTypes) { ...@@ -253,6 +253,16 @@ TEST(FunctionRef, PassByValueTypes) {
} }
} }
TEST(FunctionRef, ReferenceToIncompleteType) {
struct IncompleteType;
auto test = [](IncompleteType&) {};
absl::FunctionRef<void(IncompleteType&)> ref(test);
struct IncompleteType {};
IncompleteType obj;
ref(obj);
}
} // namespace } // namespace
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
...@@ -40,18 +40,21 @@ union VoidPtr { ...@@ -40,18 +40,21 @@ union VoidPtr {
// Chooses the best type for passing T as an argument. // Chooses the best type for passing T as an argument.
// Attempt to be close to SystemV AMD64 ABI. Objects with trivial copy ctor are // Attempt to be close to SystemV AMD64 ABI. Objects with trivial copy ctor are
// passed by value. // passed by value.
template <typename T,
bool IsLValueReference = std::is_lvalue_reference<T>::value>
struct PassByValue : std::false_type {};
template <typename T> template <typename T>
constexpr bool PassByValue() { struct PassByValue<T, /*IsLValueReference=*/false>
return !std::is_lvalue_reference<T>::value && : std::integral_constant<bool,
absl::is_trivially_copy_constructible<T>::value && absl::is_trivially_copy_constructible<T>::value &&
absl::is_trivially_copy_assignable< absl::is_trivially_copy_assignable<
typename std::remove_cv<T>::type>::value && typename std::remove_cv<T>::type>::value &&
std::is_trivially_destructible<T>::value && std::is_trivially_destructible<T>::value &&
sizeof(T) <= 2 * sizeof(void*); sizeof(T) <= 2 * sizeof(void*)> {};
}
template <typename T> template <typename T>
struct ForwardT : std::conditional<PassByValue<T>(), T, T&&> {}; struct ForwardT : std::conditional<PassByValue<T>::value, T, T&&> {};
// An Invoker takes a pointer to the type-erased invokable object, followed by // An Invoker takes a pointer to the type-erased invokable object, followed by
// the arguments that the invokable object expects. // the arguments that the invokable object expects.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment