1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* Apache License, Version 2.0 */
#include "BLI_function_ref.hh"
#include "testing/testing.h"
namespace blender::tests {
static int perform_binary_operation(int a, int b, FunctionRef<int(int, int)> operation)
{
return operation(a, b);
}
TEST(function_ref, StatelessLambda)
{
const int result = perform_binary_operation(4, 6, [](int a, int b) { return a - b; });
EXPECT_EQ(result, -2);
}
TEST(function_ref, StatefullLambda)
{
const int factor = 10;
const int result = perform_binary_operation(
2, 3, [&](int a, int b) { return factor * (a + b); });
EXPECT_EQ(result, 50);
}
static int add_two_numbers(int a, int b)
{
return a + b;
}
TEST(function_ref, StandaloneFunction)
{
const int result = perform_binary_operation(10, 5, add_two_numbers);
EXPECT_EQ(result, 15);
}
TEST(function_ref, ConstantFunction)
{
auto f = []() { return 42; };
FunctionRef<int()> ref = f;
EXPECT_EQ(ref(), 42);
}
TEST(function_ref, MutableStatefullLambda)
{
int counter = 0;
auto f = [&]() mutable { return counter++; };
FunctionRef<int()> ref = f;
EXPECT_EQ(ref(), 0);
EXPECT_EQ(ref(), 1);
EXPECT_EQ(ref(), 2);
}
TEST(function_ref, Null)
{
FunctionRef<int()> ref;
EXPECT_FALSE(ref);
auto f = []() { return 1; };
ref = f;
EXPECT_TRUE(ref);
ref = {};
EXPECT_FALSE(ref);
}
TEST(function_ref, CopyDoesNotReferenceFunctionRef)
{
auto f1 = []() { return 1; };
auto f2 = []() { return 2; };
FunctionRef<int()> x = f1;
FunctionRef<int()> y = x;
x = f2;
EXPECT_EQ(y(), 1);
}
TEST(function_ref, CopyDoesNotReferenceFunctionRef2)
{
auto f = []() { return 1; };
FunctionRef<int()> x;
FunctionRef<int()> y = f;
FunctionRef<int()> z = static_cast<const FunctionRef<int()> &&>(y);
x = z;
y = {};
EXPECT_EQ(x(), 1);
}
TEST(function_ref, ReferenceAnotherFunctionRef)
{
auto f1 = []() { return 1; };
auto f2 = []() { return 2; };
FunctionRef<int()> x = f1;
auto f3 = [&]() { return x(); };
FunctionRef<int()> y = f3;
EXPECT_EQ(y(), 1);
x = f2;
EXPECT_EQ(y(), 2);
}
TEST(function_ref, CallSafe)
{
FunctionRef<int()> f;
EXPECT_FALSE(f.call_safe().has_value());
auto func = []() { return 10; };
f = func;
EXPECT_TRUE(f.call_safe().has_value());
EXPECT_EQ(*f.call_safe(), 10);
f = {};
EXPECT_FALSE(f.call_safe().has_value());
BLI_STATIC_ASSERT((std::is_same_v<decltype(f.call_safe()), std::optional<int>>), "");
}
TEST(function_ref, CallSafeVoid)
{
FunctionRef<void()> f;
BLI_STATIC_ASSERT((std::is_same_v<decltype(f.call_safe()), void>), "");
f.call_safe();
int value = 0;
auto func = [&]() { value++; };
f = func;
f.call_safe();
EXPECT_EQ(value, 1);
}
} // namespace blender::tests
|