Fix SimpleBarrier
[folly.git] / folly / test / FunctionRefTest.cpp
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <list>
18
19 #include <folly/Function.h>
20 #include <folly/portability/GTest.h>
21
22 using folly::Function;
23 using folly::FunctionRef;
24
25 TEST(FunctionRef, Simple) {
26   int x = 1000;
27   auto lambda = [&x](int v) { return x += v; };
28
29   FunctionRef<int(int)> fref = lambda;
30   EXPECT_EQ(1005, fref(5));
31   EXPECT_EQ(1011, fref(6));
32   EXPECT_EQ(1018, fref(7));
33
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));
38
39   auto const& clambda = lambda;
40
41   FunctionRef<int(int)> fcref = clambda;
42   EXPECT_EQ(1041, fcref(5));
43   EXPECT_EQ(1047, fcref(6));
44   EXPECT_EQ(1054, fcref(7));
45
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));
50 }
51
52 TEST(FunctionRef, FunctionPtr) {
53   int (*funcptr)(int) = [](int v) { return v * v; };
54
55   FunctionRef<int(int)> fref = funcptr;
56   EXPECT_EQ(100, fref(10));
57   EXPECT_EQ(121, fref(11));
58
59   FunctionRef<int(int)> const cfref = funcptr;
60   EXPECT_EQ(100, cfref(10));
61   EXPECT_EQ(121, cfref(11));
62 }
63
64 TEST(FunctionRef, OverloadedFunctor) {
65   struct OverloadedFunctor {
66     // variant 1
67     int operator()(int x) {
68       return 100 + 1 * x;
69     }
70
71     // variant 2 (const-overload of v1)
72     int operator()(int x) const {
73       return 100 + 2 * x;
74     }
75
76     // variant 3
77     int operator()(int x, int) {
78       return 100 + 3 * x;
79     }
80
81     // variant 4 (const-overload of v3)
82     int operator()(int x, int) const {
83       return 100 + 4 * x;
84     }
85
86     // variant 5 (non-const, has no const-overload)
87     int operator()(int x, char const*) {
88       return 100 + 5 * x;
89     }
90
91     // variant 6 (const only)
92     int operator()(int x, std::vector<int> const&) const {
93       return 100 + 6 * x;
94     }
95   };
96   OverloadedFunctor of;
97   auto const& cof = of;
98
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));
103
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));
108
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));
113
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));
118
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"));
123
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}));
130
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, {}));
135 }
136
137 TEST(FunctionRef, DefaultConstructAndAssign) {
138   FunctionRef<int(int, int)> fref;
139
140   EXPECT_THROW(fref(1, 2), std::bad_function_call);
141
142   int (*func)(int, int) = [](int x, int y) { return 10 * x + y; };
143   fref = func;
144
145   EXPECT_EQ(42, fref(4, 2));
146 }
147
148 template <typename ValueType>
149 class ForEach {
150  public:
151   template <typename InputIterator>
152   ForEach(InputIterator begin, InputIterator end)
153       : func_([begin, end](FunctionRef<void(ValueType)> f) {
154           for (auto it = begin; it != end; ++it) {
155             f(*it);
156           }
157         }) {}
158
159   void operator()(FunctionRef<void(ValueType)> f) const {
160     func_(f);
161   }
162
163  private:
164   Function<void(FunctionRef<void(ValueType)>) const> const func_;
165 };
166
167 TEST(FunctionRef, ForEach) {
168   std::list<int> s{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
169
170   int sum = 0;
171
172   ForEach<int> fe{s.begin(), s.end()};
173
174   fe([&](int x) { sum += x; });
175
176   EXPECT_EQ(55, sum);
177 }