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