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