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