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