#include "base/functional/function_ref.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace {
char Moo(float) {
return 'a';
}
struct C {
long Method() { return value; }
long value;
};
}
TEST(FunctionRefTest, FreeFunction) {
[](FunctionRef<char(float)> ref) { EXPECT_EQ('a', ref(1.0)); }(&Moo);
}
TEST(FunctionRefTest, Method) {
[](FunctionRef<long(C*)> ref) {
C c = {.value = 25L};
EXPECT_EQ(25L, ref(&c));
}(&C::Method);
}
TEST(FunctionRefTest, Lambda) {
int x = 3;
auto lambda = [&x]() { return x; };
[](FunctionRef<int()> ref) { EXPECT_EQ(3, ref()); }(lambda);
}
TEST(FunctionRefTest, AbslConversion) {
{
bool called = false;
auto lambda = [&called](float) {
called = true;
return 'a';
};
FunctionRef<char(float)> ref(lambda);
[](absl::FunctionRef<char(float)> absl_ref) {
absl_ref(1.0);
}(ref.ToAbsl());
EXPECT_TRUE(called);
}
{
bool called = false;
auto lambda = [&called](float) {
called = true;
return 'a';
};
FunctionRef<char(float)> ref(lambda);
[](absl::FunctionRef<void(float)> absl_ref) {
absl_ref(1.0);
}(ref.ToAbsl());
EXPECT_TRUE(called);
}
}
TEST(FunctionRefTest, ConvertibleReturnTypes) {
{
auto lambda = []() -> bool { return true; };
[](FunctionRef<int()> ref) { EXPECT_EQ(1, ref()); }(lambda);
}
{
class Base {};
class Derived : public Base {};
auto lambda = []() -> Derived* { return nullptr; };
[](FunctionRef<Base*()> ref) { EXPECT_EQ(nullptr, ref()); }(lambda);
}
}
}