Annotate absl::FunctionRef as a view type via [[gsl::Pointer]] and absl_internal_is_view This also catches bug-prone code in our own tests. PiperOrigin-RevId: 813887857 Change-Id: Ibadcc6f9bf0ed4f9c46393a6f6fb2bcbcba5581a
diff --git a/absl/functional/function_ref.h b/absl/functional/function_ref.h index fe52853..3882eb0 100644 --- a/absl/functional/function_ref.h +++ b/absl/functional/function_ref.h
@@ -85,7 +85,7 @@ // bool Visitor(absl::FunctionRef<void(my_proto&, absl::string_view)> // callback); template <typename R, typename... Args> -class FunctionRef<R(Args...)> { +class ABSL_ATTRIBUTE_VIEW FunctionRef<R(Args...)> { protected: // Used to disable constructors for objects that are not compatible with the // signature of this FunctionRef. @@ -158,6 +158,8 @@ } #endif + using absl_internal_is_view = std::true_type; + // Call the underlying object. R operator()(Args... args) const { return invoker_(ptr_, std::forward<Args>(args)...); @@ -171,7 +173,8 @@ // Allow const qualified function signatures. Since FunctionRef requires // constness anyway we can just make this a no-op. template <typename R, typename... Args> -class FunctionRef<R(Args...) const> : private FunctionRef<R(Args...)> { +class ABSL_ATTRIBUTE_VIEW + FunctionRef<R(Args...) const> : private FunctionRef<R(Args...)> { using Base = FunctionRef<R(Args...)>; template <typename F, typename... U> @@ -215,6 +218,8 @@ : Base(arg, obj) {} #endif + using absl_internal_is_view = std::true_type; + using Base::operator(); };
diff --git a/absl/functional/function_ref_test.cc b/absl/functional/function_ref_test.cc index a0c6745..97aa3d5 100644 --- a/absl/functional/function_ref_test.cc +++ b/absl/functional/function_ref_test.cc
@@ -407,7 +407,7 @@ // producing a copy rather than another indirection. absl::FunctionRef<int()> a = +[]() { return 1; }; absl::FunctionRef<int() const> b = a; - a = []() { return 2; }; + a = +[]() { return 2; }; EXPECT_EQ(b(), 2); }