2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <folly/Function.h>
20 #include <folly/portability/GTest.h>
22 using folly::Function;
23 using folly::FunctionRef;
25 TEST(FunctionRef, Simple) {
27 auto lambda = [&x](int v) { return x += v; };
29 FunctionRef<int(int)> fref = lambda;
30 EXPECT_EQ(1005, fref(5));
31 EXPECT_EQ(1011, fref(6));
32 EXPECT_EQ(1018, fref(7));
34 FunctionRef<int(int)> const cfref = lambda;
35 EXPECT_EQ(1023, cfref(5));
36 EXPECT_EQ(1029, cfref(6));
37 EXPECT_EQ(1036, cfref(7));
39 auto const& clambda = lambda;
41 FunctionRef<int(int)> fcref = clambda;
42 EXPECT_EQ(1041, fcref(5));
43 EXPECT_EQ(1047, fcref(6));
44 EXPECT_EQ(1054, fcref(7));
46 FunctionRef<int(int)> const cfcref = clambda;
47 EXPECT_EQ(1059, cfcref(5));
48 EXPECT_EQ(1065, cfcref(6));
49 EXPECT_EQ(1072, cfcref(7));
52 TEST(FunctionRef, FunctionPtr) {
53 int (*funcptr)(int) = [](int v) { return v * v; };
55 FunctionRef<int(int)> fref = funcptr;
56 EXPECT_EQ(100, fref(10));
57 EXPECT_EQ(121, fref(11));
59 FunctionRef<int(int)> const cfref = funcptr;
60 EXPECT_EQ(100, cfref(10));
61 EXPECT_EQ(121, cfref(11));
64 TEST(FunctionRef, OverloadedFunctor) {
65 struct OverloadedFunctor {
67 int operator()(int x) {
71 // variant 2 (const-overload of v1)
72 int operator()(int x) const {
77 int operator()(int x, int) {
81 // variant 4 (const-overload of v3)
82 int operator()(int x, int) const {
86 // variant 5 (non-const, has no const-overload)
87 int operator()(int x, char const*) {
91 // variant 6 (const only)
92 int operator()(int x, std::vector<int> const&) const {
99 FunctionRef<int(int)> variant1 = of;
100 EXPECT_EQ(100 + 1 * 15, variant1(15));
101 FunctionRef<int(int)> const cvariant1 = of;
102 EXPECT_EQ(100 + 1 * 15, cvariant1(15));
104 FunctionRef<int(int)> variant2 = cof;
105 EXPECT_EQ(100 + 2 * 16, variant2(16));
106 FunctionRef<int(int)> const cvariant2 = cof;
107 EXPECT_EQ(100 + 2 * 16, cvariant2(16));
109 FunctionRef<int(int, int)> variant3 = of;
110 EXPECT_EQ(100 + 3 * 17, variant3(17, 0));
111 FunctionRef<int(int, int)> const cvariant3 = of;
112 EXPECT_EQ(100 + 3 * 17, cvariant3(17, 0));
114 FunctionRef<int(int, int)> variant4 = cof;
115 EXPECT_EQ(100 + 4 * 18, variant4(18, 0));
116 FunctionRef<int(int, int)> const cvariant4 = cof;
117 EXPECT_EQ(100 + 4 * 18, cvariant4(18, 0));
119 FunctionRef<int(int, char const*)> variant5 = of;
120 EXPECT_EQ(100 + 5 * 19, variant5(19, "foo"));
121 FunctionRef<int(int, char const*)> const cvariant5 = of;
122 EXPECT_EQ(100 + 5 * 19, cvariant5(19, "foo"));
124 FunctionRef<int(int, std::vector<int> const&)> variant6 = of;
125 EXPECT_EQ(100 + 6 * 20, variant6(20, {}));
126 EXPECT_EQ(100 + 6 * 20, variant6(20, {1, 2, 3}));
127 FunctionRef<int(int, std::vector<int> const&)> const cvariant6 = of;
128 EXPECT_EQ(100 + 6 * 20, cvariant6(20, {}));
129 EXPECT_EQ(100 + 6 * 20, cvariant6(20, {1, 2, 3}));
131 FunctionRef<int(int, std::vector<int> const&)> variant6const = cof;
132 EXPECT_EQ(100 + 6 * 21, variant6const(21, {}));
133 FunctionRef<int(int, std::vector<int> const&)> const cvariant6const = cof;
134 EXPECT_EQ(100 + 6 * 21, cvariant6const(21, {}));
137 TEST(FunctionRef, DefaultConstructAndAssign) {
138 FunctionRef<int(int, int)> fref;
141 EXPECT_THROW(fref(1, 2), std::bad_function_call);
143 int (*func)(int, int) = [](int x, int y) { return 10 * x + y; };
147 EXPECT_EQ(42, fref(4, 2));
150 template <typename ValueType>
153 template <typename InputIterator>
154 ForEach(InputIterator begin, InputIterator end)
155 : func_([begin, end](FunctionRef<void(ValueType)> f) {
156 for (auto it = begin; it != end; ++it) {
161 void operator()(FunctionRef<void(ValueType)> f) const {
166 Function<void(FunctionRef<void(ValueType)>) const> const func_;
169 TEST(FunctionRef, ForEach) {
170 std::list<int> s{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
174 ForEach<int> fe{s.begin(), s.end()};
176 fe([&](int x) { sum += x; });