Fix violations of unused-lambda-capture
[folly.git] / folly / test / FunctionTest.cpp
1 /*
2  * Copyright 2017 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 <array>
18 #include <cstdarg>
19
20 #include <folly/Function.h>
21
22 #include <folly/Memory.h>
23 #include <folly/portability/GTest.h>
24
25 using folly::Function;
26
27 namespace {
28 int func_int_int_add_25(int x) {
29   return x + 25;
30 }
31 int func_int_int_add_111(int x) {
32   return x + 111;
33 }
34 float floatMult(float a, float b) {
35   return a * b;
36 }
37
38 template <class T, size_t S>
39 struct Functor {
40   std::array<T, S> data = {{0}};
41
42   // Two operator() with different argument types.
43   // The InvokeReference tests use both
44   T const& operator()(size_t index) const {
45     return data[index];
46   }
47   T operator()(size_t index, T const& value) {
48     T oldvalue = data[index];
49     data[index] = value;
50     return oldvalue;
51   }
52 };
53
54 template <typename Ret, typename... Args>
55 void deduceArgs(Function<Ret(Args...)>) {}
56
57 struct CallableButNotCopyable {
58   CallableButNotCopyable() {}
59   CallableButNotCopyable(CallableButNotCopyable const&) = delete;
60   CallableButNotCopyable(CallableButNotCopyable&&) = delete;
61   CallableButNotCopyable& operator=(CallableButNotCopyable const&) = delete;
62   CallableButNotCopyable& operator=(CallableButNotCopyable&&) = delete;
63   template <class... Args>
64   void operator()(Args&&...) const {}
65 };
66
67 } // namespace
68
69 // TEST =====================================================================
70 // Test constructibility and non-constructibility for some tricky conversions
71 static_assert(
72     !std::is_assignable<Function<void()>, CallableButNotCopyable>::value,
73     "");
74 static_assert(
75     !std::is_constructible<Function<void()>, CallableButNotCopyable&>::value,
76     "");
77 static_assert(
78     !std::is_constructible<Function<void() const>, CallableButNotCopyable>::
79         value,
80     "");
81 static_assert(
82     !std::is_constructible<Function<void() const>, CallableButNotCopyable&>::
83         value,
84     "");
85
86 static_assert(
87     !std::is_assignable<Function<void()>, CallableButNotCopyable>::value,
88     "");
89 static_assert(
90     !std::is_assignable<Function<void()>, CallableButNotCopyable&>::value,
91     "");
92 static_assert(
93     !std::is_assignable<Function<void() const>, CallableButNotCopyable>::value,
94     "");
95 static_assert(
96     !std::is_assignable<Function<void() const>, CallableButNotCopyable&>::value,
97     "");
98
99 static_assert(
100     std::is_constructible<Function<int(int)>, Function<int(int) const>>::value,
101     "");
102 static_assert(
103     !std::is_constructible<Function<int(int) const>, Function<int(int)>>::value,
104     "");
105 static_assert(
106     std::is_constructible<Function<int(short)>, Function<short(int) const>>::
107         value,
108     "");
109 static_assert(
110     !std::is_constructible<Function<int(short) const>, Function<short(int)>>::
111         value,
112     "");
113 static_assert(
114     !std::is_constructible<Function<int(int)>, Function<int(int) const>&>::
115         value,
116     "");
117 static_assert(
118     !std::is_constructible<Function<int(int) const>, Function<int(int)>&>::
119         value,
120     "");
121 static_assert(
122     !std::is_constructible<Function<int(short)>, Function<short(int) const>&>::
123         value,
124     "");
125 static_assert(
126     !std::is_constructible<Function<int(short) const>, Function<short(int)>&>::
127         value,
128     "");
129
130 static_assert(
131     std::is_assignable<Function<int(int)>, Function<int(int) const>>::value,
132     "");
133 static_assert(
134     !std::is_assignable<Function<int(int) const>, Function<int(int)>>::value,
135     "");
136 static_assert(
137     std::is_assignable<Function<int(short)>, Function<short(int) const>>::value,
138     "");
139 static_assert(
140     !std::is_assignable<Function<int(short) const>, Function<short(int)>>::
141         value,
142     "");
143 static_assert(
144     !std::is_assignable<Function<int(int)>, Function<int(int) const>&>::value,
145     "");
146 static_assert(
147     !std::is_assignable<Function<int(int) const>, Function<int(int)>&>::value,
148     "");
149 static_assert(
150     !std::is_assignable<Function<int(short)>, Function<short(int) const>&>::
151         value,
152     "");
153 static_assert(
154     !std::is_assignable<Function<int(short) const>, Function<short(int)>&>::
155         value,
156     "");
157
158 static_assert(
159     std::is_nothrow_constructible<
160         Function<int(int)>,
161         Function<int(int) const>>::value,
162     "");
163 static_assert(
164     !std::is_nothrow_constructible<
165         Function<int(short)>,
166         Function<short(int) const>>::value,
167     "");
168 static_assert(
169     std::is_nothrow_assignable<Function<int(int)>, Function<int(int) const>>::
170         value,
171     "");
172 static_assert(
173     !std::is_nothrow_assignable<
174         Function<int(short)>,
175         Function<short(int) const>>::value,
176     "");
177
178 // TEST =====================================================================
179 // InvokeFunctor & InvokeReference
180
181 TEST(Function, InvokeFunctor) {
182   Functor<int, 100> func;
183   static_assert(
184       sizeof(func) > sizeof(Function<int(size_t)>),
185       "sizeof(Function) is much larger than expected");
186   func(5, 123);
187
188   Function<int(size_t) const> getter = std::move(func);
189
190   // Function will allocate memory on the heap to store the functor object
191   EXPECT_TRUE(getter.hasAllocatedMemory());
192
193   EXPECT_EQ(123, getter(5));
194 }
195
196 TEST(Function, InvokeReference) {
197   Functor<int, 10> func;
198   func(5, 123);
199
200   // Have Functions for getter and setter, both referencing the same funtor
201   Function<int(size_t) const> getter = std::ref(func);
202   Function<int(size_t, int)> setter = std::ref(func);
203
204   EXPECT_EQ(123, getter(5));
205   EXPECT_EQ(123, setter(5, 456));
206   EXPECT_EQ(456, setter(5, 567));
207   EXPECT_EQ(567, getter(5));
208 }
209
210 // TEST =====================================================================
211 // Emptiness
212
213 TEST(Function, Emptiness_T) {
214   Function<int(int)> f;
215   EXPECT_EQ(f, nullptr);
216   EXPECT_EQ(nullptr, f);
217   EXPECT_FALSE(f);
218   EXPECT_THROW(f(98), std::bad_function_call);
219
220   Function<int(int)> g([](int x) { return x + 1; });
221   EXPECT_NE(g, nullptr);
222   EXPECT_NE(nullptr, g);
223   // Explicitly convert to bool to work around
224   // https://github.com/google/googletest/issues/429
225   EXPECT_TRUE(bool(g));
226   EXPECT_EQ(100, g(99));
227
228   Function<int(int)> h(&func_int_int_add_25);
229   EXPECT_NE(h, nullptr);
230   EXPECT_NE(nullptr, h);
231   EXPECT_TRUE(bool(h));
232   EXPECT_EQ(125, h(100));
233
234   h = {};
235   EXPECT_EQ(h, nullptr);
236   EXPECT_EQ(nullptr, h);
237   EXPECT_FALSE(h);
238   EXPECT_THROW(h(101), std::bad_function_call);
239 }
240
241 // TEST =====================================================================
242 // Swap
243
244 template <bool UseSwapMethod>
245 void swap_test() {
246   Function<int(int)> mf1(func_int_int_add_25);
247   Function<int(int)> mf2(func_int_int_add_111);
248
249   EXPECT_EQ(125, mf1(100));
250   EXPECT_EQ(211, mf2(100));
251
252   if (UseSwapMethod) {
253     mf1.swap(mf2);
254   } else {
255     swap(mf1, mf2);
256   }
257
258   EXPECT_EQ(125, mf2(100));
259   EXPECT_EQ(211, mf1(100));
260
261   Function<int(int)> mf3(nullptr);
262   EXPECT_EQ(mf3, nullptr);
263
264   if (UseSwapMethod) {
265     mf1.swap(mf3);
266   } else {
267     swap(mf1, mf3);
268   }
269
270   EXPECT_EQ(211, mf3(100));
271   EXPECT_EQ(nullptr, mf1);
272
273   Function<int(int)> mf4([](int x) { return x + 222; });
274   EXPECT_EQ(322, mf4(100));
275
276   if (UseSwapMethod) {
277     mf4.swap(mf3);
278   } else {
279     swap(mf4, mf3);
280   }
281   EXPECT_EQ(211, mf4(100));
282   EXPECT_EQ(322, mf3(100));
283
284   if (UseSwapMethod) {
285     mf3.swap(mf1);
286   } else {
287     swap(mf3, mf1);
288   }
289   EXPECT_EQ(nullptr, mf3);
290   EXPECT_EQ(322, mf1(100));
291 }
292 TEST(Function, SwapMethod) {
293   swap_test<true>();
294 }
295 TEST(Function, SwapFunction) {
296   swap_test<false>();
297 }
298
299 // TEST =====================================================================
300 // Bind
301
302 TEST(Function, Bind) {
303   Function<float(float, float)> fnc = floatMult;
304   auto task = std::bind(std::move(fnc), 2.f, 4.f);
305   EXPECT_THROW(fnc(0, 0), std::bad_function_call);
306   EXPECT_EQ(8, task());
307   auto task2(std::move(task));
308   EXPECT_THROW(task(), std::bad_function_call);
309   EXPECT_EQ(8, task2());
310 }
311
312 // TEST =====================================================================
313 // NonCopyableLambda
314
315 TEST(Function, NonCopyableLambda) {
316   auto unique_ptr_int = std::make_unique<int>(900);
317   EXPECT_EQ(900, *unique_ptr_int);
318
319   struct {
320     char data[64];
321   } fooData = {{0}};
322   (void)fooData; // suppress gcc warning about fooData not being used
323
324   auto functor = std::bind(
325       [fooData](std::unique_ptr<int>& up) mutable {
326         (void)fooData;
327         return ++*up;
328       },
329       std::move(unique_ptr_int));
330
331   EXPECT_EQ(901, functor());
332
333   Function<int(void)> func = std::move(functor);
334   EXPECT_TRUE(func.hasAllocatedMemory());
335
336   EXPECT_EQ(902, func());
337 }
338
339 // TEST =====================================================================
340 // OverloadedFunctor
341
342 TEST(Function, OverloadedFunctor) {
343   struct OverloadedFunctor {
344     // variant 1
345     int operator()(int x) {
346       return 100 + 1 * x;
347     }
348
349     // variant 2 (const-overload of v1)
350     int operator()(int x) const {
351       return 100 + 2 * x;
352     }
353
354     // variant 3
355     int operator()(int x, int) {
356       return 100 + 3 * x;
357     }
358
359     // variant 4 (const-overload of v3)
360     int operator()(int x, int) const {
361       return 100 + 4 * x;
362     }
363
364     // variant 5 (non-const, has no const-overload)
365     int operator()(int x, char const*) {
366       return 100 + 5 * x;
367     }
368
369     // variant 6 (const only)
370     int operator()(int x, std::vector<int> const&) const {
371       return 100 + 6 * x;
372     }
373   };
374   OverloadedFunctor of;
375
376   Function<int(int)> variant1 = of;
377   EXPECT_EQ(100 + 1 * 15, variant1(15));
378
379   Function<int(int) const> variant2 = of;
380   EXPECT_EQ(100 + 2 * 16, variant2(16));
381
382   Function<int(int, int)> variant3 = of;
383   EXPECT_EQ(100 + 3 * 17, variant3(17, 0));
384
385   Function<int(int, int) const> variant4 = of;
386   EXPECT_EQ(100 + 4 * 18, variant4(18, 0));
387
388   Function<int(int, char const*)> variant5 = of;
389   EXPECT_EQ(100 + 5 * 19, variant5(19, "foo"));
390
391   Function<int(int, std::vector<int> const&)> variant6 = of;
392   EXPECT_EQ(100 + 6 * 20, variant6(20, {}));
393   EXPECT_EQ(100 + 6 * 20, variant6(20, {1, 2, 3}));
394
395   Function<int(int, std::vector<int> const&) const> variant6const = of;
396   EXPECT_EQ(100 + 6 * 21, variant6const(21, {}));
397
398   // Cast const-functions to non-const and the other way around: if the functor
399   // has both const and non-const operator()s for a given parameter signature,
400   // constructing a Function must select one of them, depending on
401   // whether the function type template parameter is const-qualified or not.
402   // When the const-ness is later changed (by moving the
403   // Function<R(Args...)const> into a Function<R(Args...)> or by
404   // calling the folly::constCastFunction which moves it into a
405   // Function<R(Args...)const>), the Function must still execute
406   // the initially selected function.
407
408   auto variant1_const = folly::constCastFunction(std::move(variant1));
409   EXPECT_THROW(variant1(0), std::bad_function_call);
410   EXPECT_EQ(100 + 1 * 22, variant1_const(22));
411
412   Function<int(int)> variant2_nonconst = std::move(variant2);
413   EXPECT_THROW(variant2(0), std::bad_function_call);
414   EXPECT_EQ(100 + 2 * 23, variant2_nonconst(23));
415
416   auto variant3_const = folly::constCastFunction(std::move(variant3));
417   EXPECT_THROW(variant3(0, 0), std::bad_function_call);
418   EXPECT_EQ(100 + 3 * 24, variant3_const(24, 0));
419
420   Function<int(int, int)> variant4_nonconst = std::move(variant4);
421   EXPECT_THROW(variant4(0, 0), std::bad_function_call);
422   EXPECT_EQ(100 + 4 * 25, variant4_nonconst(25, 0));
423
424   auto variant5_const = folly::constCastFunction(std::move(variant5));
425   EXPECT_THROW(variant5(0, ""), std::bad_function_call);
426   EXPECT_EQ(100 + 5 * 26, variant5_const(26, "foo"));
427
428   auto variant6_const = folly::constCastFunction(std::move(variant6));
429   EXPECT_THROW(variant6(0, {}), std::bad_function_call);
430   EXPECT_EQ(100 + 6 * 27, variant6_const(27, {}));
431
432   Function<int(int, std::vector<int> const&)> variant6const_nonconst =
433       std::move(variant6const);
434   EXPECT_THROW(variant6const(0, {}), std::bad_function_call);
435   EXPECT_EQ(100 + 6 * 28, variant6const_nonconst(28, {}));
436 }
437
438 // TEST =====================================================================
439 // Lambda
440
441 TEST(Function, Lambda) {
442   // Non-mutable lambdas: can be stored in a non-const...
443   Function<int(int)> func = [](int x) { return 1000 + x; };
444   EXPECT_EQ(1001, func(1));
445
446   // ...as well as in a const Function
447   Function<int(int) const> func_const = [](int x) { return 2000 + x; };
448   EXPECT_EQ(2001, func_const(1));
449
450   // Mutable lambda: can only be stored in a const Function:
451   int number = 3000;
452   Function<int()> func_mutable = [number]() mutable { return ++number; };
453   EXPECT_EQ(3001, func_mutable());
454   EXPECT_EQ(3002, func_mutable());
455
456   // test after const-casting
457
458   Function<int(int) const> func_made_const =
459       folly::constCastFunction(std::move(func));
460   EXPECT_EQ(1002, func_made_const(2));
461   EXPECT_THROW(func(0), std::bad_function_call);
462
463   Function<int(int)> func_const_made_nonconst = std::move(func_const);
464   EXPECT_EQ(2002, func_const_made_nonconst(2));
465   EXPECT_THROW(func_const(0), std::bad_function_call);
466
467   Function<int() const> func_mutable_made_const =
468       folly::constCastFunction(std::move(func_mutable));
469   EXPECT_EQ(3003, func_mutable_made_const());
470   EXPECT_EQ(3004, func_mutable_made_const());
471   EXPECT_THROW(func_mutable(), std::bad_function_call);
472 }
473
474 // TEST =====================================================================
475 // DataMember & MemberFunction
476
477 struct MemberFunc {
478   int x;
479   int getX() const {
480     return x;
481   }
482   void setX(int xx) {
483     x = xx;
484   }
485 };
486
487 TEST(Function, DataMember) {
488   MemberFunc mf;
489   MemberFunc const& cmf = mf;
490   mf.x = 123;
491
492   Function<int(MemberFunc const*)> data_getter1 = &MemberFunc::x;
493   EXPECT_EQ(123, data_getter1(&cmf));
494   Function<int(MemberFunc*)> data_getter2 = &MemberFunc::x;
495   EXPECT_EQ(123, data_getter2(&mf));
496   Function<int(MemberFunc const&)> data_getter3 = &MemberFunc::x;
497   EXPECT_EQ(123, data_getter3(cmf));
498   Function<int(MemberFunc&)> data_getter4 = &MemberFunc::x;
499   EXPECT_EQ(123, data_getter4(mf));
500 }
501
502 TEST(Function, MemberFunction) {
503   MemberFunc mf;
504   MemberFunc const& cmf = mf;
505   mf.x = 123;
506
507   Function<int(MemberFunc const*)> getter1 = &MemberFunc::getX;
508   EXPECT_EQ(123, getter1(&cmf));
509   Function<int(MemberFunc*)> getter2 = &MemberFunc::getX;
510   EXPECT_EQ(123, getter2(&mf));
511   Function<int(MemberFunc const&)> getter3 = &MemberFunc::getX;
512   EXPECT_EQ(123, getter3(cmf));
513   Function<int(MemberFunc&)> getter4 = &MemberFunc::getX;
514   EXPECT_EQ(123, getter4(mf));
515
516   Function<void(MemberFunc*, int)> setter1 = &MemberFunc::setX;
517   setter1(&mf, 234);
518   EXPECT_EQ(234, mf.x);
519
520   Function<void(MemberFunc&, int)> setter2 = &MemberFunc::setX;
521   setter2(mf, 345);
522   EXPECT_EQ(345, mf.x);
523 }
524
525 // TEST =====================================================================
526 // CaptureCopyMoveCount & ParameterCopyMoveCount
527
528 class CopyMoveTracker {
529  public:
530   struct ConstructorTag {};
531
532   CopyMoveTracker() = delete;
533   explicit CopyMoveTracker(ConstructorTag)
534       : data_(std::make_shared<std::pair<size_t, size_t>>(0, 0)) {}
535
536   CopyMoveTracker(CopyMoveTracker const& o) noexcept : data_(o.data_) {
537     ++data_->first;
538   }
539   CopyMoveTracker& operator=(CopyMoveTracker const& o) noexcept {
540     data_ = o.data_;
541     ++data_->first;
542     return *this;
543   }
544
545   CopyMoveTracker(CopyMoveTracker&& o) noexcept : data_(o.data_) {
546     ++data_->second;
547   }
548   CopyMoveTracker& operator=(CopyMoveTracker&& o) noexcept {
549     data_ = o.data_;
550     ++data_->second;
551     return *this;
552   }
553
554   size_t copyCount() const {
555     return data_->first;
556   }
557   size_t moveCount() const {
558     return data_->second;
559   }
560   size_t refCount() const {
561     return data_.use_count();
562   }
563   void resetCounters() {
564     data_->first = data_->second = 0;
565   }
566
567  private:
568   // copy, move
569   std::shared_ptr<std::pair<size_t, size_t>> data_;
570 };
571
572 TEST(Function, CaptureCopyMoveCount) {
573   // This test checks that no unnecessary copies/moves are made.
574
575   CopyMoveTracker cmt(CopyMoveTracker::ConstructorTag{});
576   EXPECT_EQ(0, cmt.copyCount());
577   EXPECT_EQ(0, cmt.moveCount());
578   EXPECT_EQ(1, cmt.refCount());
579
580   // Move into lambda, move lambda into Function
581   auto lambda1 = [cmt = std::move(cmt)]() {
582     return cmt.moveCount();
583   };
584   Function<size_t(void)> uf1 = std::move(lambda1);
585
586   // Max copies: 0. Max copy+moves: 2.
587   EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
588   EXPECT_LE(cmt.copyCount(), 0);
589
590   cmt.resetCounters();
591
592   // Move into lambda, copy lambda into Function
593   auto lambda2 = [cmt = std::move(cmt)]() {
594     return cmt.moveCount();
595   };
596   Function<size_t(void)> uf2 = lambda2;
597
598   // Max copies: 1. Max copy+moves: 2.
599   EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
600   EXPECT_LE(cmt.copyCount(), 1);
601
602   // Invoking Function must not make copies/moves of the callable
603   cmt.resetCounters();
604   uf1();
605   uf2();
606   EXPECT_EQ(0, cmt.copyCount());
607   EXPECT_EQ(0, cmt.moveCount());
608 }
609
610 TEST(Function, ParameterCopyMoveCount) {
611   // This test checks that no unnecessary copies/moves are made.
612
613   CopyMoveTracker cmt(CopyMoveTracker::ConstructorTag{});
614   EXPECT_EQ(0, cmt.copyCount());
615   EXPECT_EQ(0, cmt.moveCount());
616   EXPECT_EQ(1, cmt.refCount());
617
618   // pass by value
619   Function<size_t(CopyMoveTracker)> uf1 = [](CopyMoveTracker c) {
620     return c.moveCount();
621   };
622
623   cmt.resetCounters();
624   uf1(cmt);
625   // Max copies: 1. Max copy+moves: 2.
626   EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
627   EXPECT_LE(cmt.copyCount(), 1);
628
629   cmt.resetCounters();
630   uf1(std::move(cmt));
631   // Max copies: 1. Max copy+moves: 2.
632   EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
633   EXPECT_LE(cmt.copyCount(), 0);
634
635   // pass by reference
636   Function<size_t(CopyMoveTracker&)> uf2 = [](CopyMoveTracker& c) {
637     return c.moveCount();
638   };
639
640   cmt.resetCounters();
641   uf2(cmt);
642   // Max copies: 0. Max copy+moves: 0.
643   EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 0);
644   EXPECT_LE(cmt.copyCount(), 0);
645
646   // pass by const reference
647   Function<size_t(CopyMoveTracker const&)> uf3 = [](CopyMoveTracker const& c) {
648     return c.moveCount();
649   };
650
651   cmt.resetCounters();
652   uf3(cmt);
653   // Max copies: 0. Max copy+moves: 0.
654   EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 0);
655   EXPECT_LE(cmt.copyCount(), 0);
656
657   // pass by rvalue reference
658   Function<size_t(CopyMoveTracker &&)> uf4 = [](CopyMoveTracker&& c) {
659     return c.moveCount();
660   };
661
662   cmt.resetCounters();
663   uf4(std::move(cmt));
664   // Max copies: 0. Max copy+moves: 0.
665   EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 0);
666   EXPECT_LE(cmt.copyCount(), 0);
667 }
668
669 // TEST =====================================================================
670 // VariadicTemplate & VariadicArguments
671
672 struct VariadicTemplateSum {
673   int operator()() const {
674     return 0;
675   }
676   template <class... Args>
677   int operator()(int x, Args... args) const {
678     return x + (*this)(args...);
679   }
680 };
681
682 TEST(Function, VariadicTemplate) {
683   Function<int(int)> uf1 = VariadicTemplateSum();
684   Function<int(int, int)> uf2 = VariadicTemplateSum();
685   Function<int(int, int, int)> uf3 = VariadicTemplateSum();
686
687   EXPECT_EQ(66, uf1(66));
688   EXPECT_EQ(99, uf2(55, 44));
689   EXPECT_EQ(66, uf3(33, 22, 11));
690 }
691
692 struct VariadicArgumentsSum {
693   int operator()(int count, ...) const {
694     int result = 0;
695     va_list args;
696     va_start(args, count);
697     for (int i = 0; i < count; ++i) {
698       result += va_arg(args, int);
699     }
700     va_end(args);
701     return result;
702   }
703 };
704
705 TEST(Function, VariadicArguments) {
706   Function<int(int)> uf1 = VariadicArgumentsSum();
707   Function<int(int, int)> uf2 = VariadicArgumentsSum();
708   Function<int(int, int, int)> uf3 = VariadicArgumentsSum();
709
710   EXPECT_EQ(0, uf1(0));
711   EXPECT_EQ(66, uf2(1, 66));
712   EXPECT_EQ(99, uf3(2, 55, 44));
713 }
714
715 // TEST =====================================================================
716 // SafeCaptureByReference
717
718 // A function can use Function const& as a parameter to signal that it
719 // is safe to pass a lambda that captures local variables by reference.
720 // It is safe because we know the function called can only invoke the
721 // Function until it returns. It can't store a copy of the Function
722 // (because it's not copyable), and it can't move the Function somewhere
723 // else (because it gets only a const&).
724
725 template <typename T>
726 void for_each(
727     T const& range,
728     Function<void(typename T::value_type const&) const> const& func) {
729   for (auto const& elem : range) {
730     func(elem);
731   }
732 }
733
734 TEST(Function, SafeCaptureByReference) {
735   std::vector<int> const vec = {20, 30, 40, 2, 3, 4, 200, 300, 400};
736
737   int sum = 0;
738
739   // for_each's second parameter is of type Function<...> const&.
740   // Hence we know we can safely pass it a lambda that references local
741   // variables. There is no way the reference to x will be stored anywhere.
742   for_each<std::vector<int>>(vec, [&sum](int x) { sum += x; });
743
744   // gcc versions before 4.9 cannot deduce the type T in the above call
745   // to for_each. Modern compiler versions can compile the following line:
746   //   for_each(vec, [&sum](int x) { sum += x; });
747
748   EXPECT_EQ(999, sum);
749 }
750
751 // TEST =====================================================================
752 // IgnoreReturnValue
753
754 TEST(Function, IgnoreReturnValue) {
755   int x = 95;
756
757   // Assign a lambda that return int to a folly::Function that returns void.
758   Function<void()> f = [&]() -> int { return ++x; };
759
760   EXPECT_EQ(95, x);
761   f();
762   EXPECT_EQ(96, x);
763
764   Function<int()> g = [&]() -> int { return ++x; };
765   Function<void()> cg = std::move(g);
766
767   EXPECT_EQ(96, x);
768   cg();
769   EXPECT_EQ(97, x);
770 }
771
772 // TEST =====================================================================
773 // ReturnConvertible, ConvertReturnType
774
775 TEST(Function, ReturnConvertible) {
776   struct CBase {
777     int x;
778   };
779   struct CDerived : CBase {};
780
781   Function<double()> f1 = []() -> int { return 5; };
782   EXPECT_EQ(5.0, f1());
783
784   Function<int()> f2 = []() -> double { return 5.2; };
785   EXPECT_EQ(5, f2());
786
787   CDerived derived;
788   derived.x = 55;
789
790   Function<CBase const&()> f3 = [&]() -> CDerived const& { return derived; };
791   EXPECT_EQ(55, f3().x);
792
793   Function<CBase const&()> f4 = [&]() -> CDerived& { return derived; };
794   EXPECT_EQ(55, f4().x);
795
796   Function<CBase&()> f5 = [&]() -> CDerived& { return derived; };
797   EXPECT_EQ(55, f5().x);
798
799   Function<CBase const*()> f6 = [&]() -> CDerived const* { return &derived; };
800   EXPECT_EQ(f6()->x, 55);
801
802   Function<CBase const*()> f7 = [&]() -> CDerived* { return &derived; };
803   EXPECT_EQ(55, f7()->x);
804
805   Function<CBase*()> f8 = [&]() -> CDerived* { return &derived; };
806   EXPECT_EQ(55, f8()->x);
807
808   Function<CBase()> f9 = [&]() -> CDerived {
809     auto d = derived;
810     d.x = 66;
811     return d;
812   };
813   EXPECT_EQ(66, f9().x);
814 }
815
816 TEST(Function, ConvertReturnType) {
817   struct CBase {
818     int x;
819   };
820   struct CDerived : CBase {};
821
822   Function<int()> f1 = []() -> int { return 5; };
823   Function<double()> cf1 = std::move(f1);
824   EXPECT_EQ(5.0, cf1());
825   Function<int()> ccf1 = std::move(cf1);
826   EXPECT_EQ(5, ccf1());
827
828   Function<double()> f2 = []() -> double { return 5.2; };
829   Function<int()> cf2 = std::move(f2);
830   EXPECT_EQ(5, cf2());
831   Function<double()> ccf2 = std::move(cf2);
832   EXPECT_EQ(5.0, ccf2());
833
834   CDerived derived;
835   derived.x = 55;
836
837   Function<CDerived const&()> f3 = [&]() -> CDerived const& { return derived; };
838   Function<CBase const&()> cf3 = std::move(f3);
839   EXPECT_EQ(55, cf3().x);
840
841   Function<CDerived&()> f4 = [&]() -> CDerived& { return derived; };
842   Function<CBase const&()> cf4 = std::move(f4);
843   EXPECT_EQ(55, cf4().x);
844
845   Function<CDerived&()> f5 = [&]() -> CDerived& { return derived; };
846   Function<CBase&()> cf5 = std::move(f5);
847   EXPECT_EQ(55, cf5().x);
848
849   Function<CDerived const*()> f6 = [&]() -> CDerived const* {
850     return &derived;
851   };
852   Function<CBase const*()> cf6 = std::move(f6);
853   EXPECT_EQ(55, cf6()->x);
854
855   Function<CDerived const*()> f7 = [&]() -> CDerived* { return &derived; };
856   Function<CBase const*()> cf7 = std::move(f7);
857   EXPECT_EQ(55, cf7()->x);
858
859   Function<CDerived*()> f8 = [&]() -> CDerived* { return &derived; };
860   Function<CBase*()> cf8 = std::move(f8);
861   EXPECT_EQ(55, cf8()->x);
862
863   Function<CDerived()> f9 = [&]() -> CDerived {
864     auto d = derived;
865     d.x = 66;
866     return d;
867   };
868   Function<CBase()> cf9 = std::move(f9);
869   EXPECT_EQ(66, cf9().x);
870 }
871
872 // TEST =====================================================================
873 // asStdFunction_*
874
875 TEST(Function, asStdFunction_void) {
876   int i = 0;
877   folly::Function<void()> f = [&] { ++i; };
878   auto sf = std::move(f).asStdFunction();
879   static_assert(std::is_same<decltype(sf), std::function<void()>>::value,
880       "std::function has wrong type");
881   sf();
882   EXPECT_EQ(1, i);
883 }
884
885 TEST(Function, asStdFunction_void_const) {
886   int i = 0;
887   folly::Function<void() const> f = [&] { ++i; };
888   auto sf = std::move(f).asStdFunction();
889   static_assert(std::is_same<decltype(sf), std::function<void()>>::value,
890       "std::function has wrong type");
891   sf();
892   EXPECT_EQ(1, i);
893 }
894
895 TEST(Function, asStdFunction_return) {
896   int i = 0;
897   folly::Function<int()> f = [&] {
898     ++i;
899     return 42;
900   };
901   auto sf = std::move(f).asStdFunction();
902   static_assert(std::is_same<decltype(sf), std::function<int()>>::value,
903       "std::function has wrong type");
904   EXPECT_EQ(42, sf());
905   EXPECT_EQ(1, i);
906 }
907
908 TEST(Function, asStdFunction_return_const) {
909   int i = 0;
910   folly::Function<int() const> f = [&] {
911     ++i;
912     return 42;
913   };
914   auto sf = std::move(f).asStdFunction();
915   static_assert(std::is_same<decltype(sf), std::function<int()>>::value,
916       "std::function has wrong type");
917   EXPECT_EQ(42, sf());
918   EXPECT_EQ(1, i);
919 }
920
921 TEST(Function, asStdFunction_args) {
922   int i = 0;
923   folly::Function<void(int, int)> f = [&](int x, int y) {
924     ++i;
925     return x + y;
926   };
927   auto sf = std::move(f).asStdFunction();
928   static_assert(std::is_same<decltype(sf), std::function<void(int, int)>>::value,
929       "std::function has wrong type");
930   sf(42, 42);
931   EXPECT_EQ(1, i);
932 }
933
934 TEST(Function, asStdFunction_args_const) {
935   int i = 0;
936   folly::Function<void(int, int) const> f = [&](int x, int y) {
937     ++i;
938     return x + y;
939   };
940   auto sf = std::move(f).asStdFunction();
941   static_assert(std::is_same<decltype(sf), std::function<void(int, int)>>::value,
942       "std::function has wrong type");
943   sf(42, 42);
944   EXPECT_EQ(1, i);
945 }
946
947 // TEST =====================================================================
948 // asSharedProxy_*
949
950 TEST(Function, asSharedProxy_void) {
951   int i = 0;
952   folly::Function<void()> f = [&i] { ++i; };
953   auto sp = std::move(f).asSharedProxy();
954   auto spcopy = sp;
955   sp();
956   EXPECT_EQ(1, i);
957   spcopy();
958   EXPECT_EQ(2, i);
959 }
960
961 TEST(Function, asSharedProxy_void_const) {
962   int i = 0;
963   folly::Function<void() const> f = [&i] { ++i; };
964   auto sp = std::move(f).asSharedProxy();
965   auto spcopy = sp;
966   sp();
967   EXPECT_EQ(1, i);
968   spcopy();
969   EXPECT_EQ(2, i);
970 }
971
972 TEST(Function, asSharedProxy_return) {
973   folly::Function<int()> f = [i = 0]() mutable {
974     ++i;
975     return i;
976   };
977   auto sp = std::move(f).asSharedProxy();
978   auto spcopy = sp;
979   EXPECT_EQ(1, sp());
980   EXPECT_EQ(2, spcopy());
981 }
982
983 TEST(Function, asSharedProxy_return_const) {
984   int i = 0;
985   folly::Function<int() const> f = [&i] {
986     ++i;
987     return i;
988   };
989   auto sp = std::move(f).asSharedProxy();
990   auto spcopy = sp;
991   EXPECT_EQ(1, sp());
992   EXPECT_EQ(2, spcopy());
993 }
994
995 TEST(Function, asSharedProxy_args) {
996   int i = 0;
997   folly::Function<int(int, int)> f = [&](int x, int y) mutable {
998     ++i;
999     return x + y * 2;
1000   };
1001   auto sp = std::move(f).asSharedProxy();
1002   auto spcopy = sp;
1003   EXPECT_EQ(120, sp(100, 10));
1004   EXPECT_EQ(1, i);
1005   EXPECT_EQ(120, spcopy(100, 10));
1006   EXPECT_EQ(2, i);
1007 }
1008
1009 TEST(Function, asSharedProxy_args_const) {
1010   int i = 0;
1011   folly::Function<int(int, int) const> f = [&i](int x, int y) {
1012     ++i;
1013     return x * 100 + y * 10 + i;
1014   };
1015   auto sp = std::move(f).asSharedProxy();
1016   auto spcopy = sp;
1017   EXPECT_EQ(561, sp(5, 6));
1018   EXPECT_EQ(562, spcopy(5, 6));
1019 }
1020
1021 TEST(Function, NoAllocatedMemoryAfterMove) {
1022   Functor<int, 100> foo;
1023
1024   Function<int(size_t)> func = foo;
1025   EXPECT_TRUE(func.hasAllocatedMemory());
1026
1027   Function<int(size_t)> func2 = std::move(func);
1028   EXPECT_TRUE(func2.hasAllocatedMemory());
1029   EXPECT_FALSE(func.hasAllocatedMemory());
1030 }
1031
1032 TEST(Function, ConstCastEmbedded) {
1033   int x = 0;
1034   auto functor = [&x]() { ++x; };
1035
1036   Function<void() const> func(functor);
1037   EXPECT_FALSE(func.hasAllocatedMemory());
1038
1039   Function<void()> func2(std::move(func));
1040   EXPECT_FALSE(func2.hasAllocatedMemory());
1041 }
1042
1043 TEST(Function, EmptyAfterConstCast) {
1044   Function<int(size_t)> func;
1045   EXPECT_FALSE(func);
1046
1047   Function<int(size_t) const> func2 = constCastFunction(std::move(func));
1048   EXPECT_FALSE(func2);
1049 }
1050
1051 TEST(Function, SelfStdSwap) {
1052   Function<int()> f = [] { return 42; };
1053   f.swap(f);
1054   EXPECT_TRUE(bool(f));
1055   EXPECT_EQ(42, f());
1056   std::swap(f, f);
1057   EXPECT_TRUE(bool(f));
1058   EXPECT_EQ(42, f());
1059   folly::swap(f, f);
1060   EXPECT_TRUE(bool(f));
1061   EXPECT_EQ(42, f());
1062 }
1063
1064 TEST(Function, SelfMove) {
1065   Function<int()> f = [] { return 42; };
1066   Function<int()>& g = f;
1067   f = std::move(g); // shouldn't crash!
1068   (void)bool(f); // valid but unspecified state
1069   f = [] { return 43; };
1070   EXPECT_TRUE(bool(f));
1071   EXPECT_EQ(43, f());
1072 }
1073
1074 TEST(Function, DeducableArguments) {
1075   deduceArgs(Function<void()>{[] {}});
1076   deduceArgs(Function<void(int, float)>{[](int, float) {}});
1077   deduceArgs(Function<int(int, float)>{[](int i, float) { return i; }});
1078 }
1079
1080 TEST(Function, CtorWithCopy) {
1081   struct X {
1082     X() {}
1083     X(X const&) noexcept(true) {}
1084     X& operator=(X const&) = default;
1085   };
1086   struct Y {
1087     Y() {}
1088     Y(Y const&) noexcept(false) {}
1089     Y(Y&&) noexcept(true) {}
1090     Y& operator=(Y&&) = default;
1091     Y& operator=(Y const&) = default;
1092   };
1093   auto lx = [x = X()]{};
1094   auto ly = [y = Y()]{};
1095   EXPECT_TRUE(noexcept(Function<void()>(lx)));
1096   EXPECT_FALSE(noexcept(Function<void()>(ly)));
1097 }