2 * Copyright 2017 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <folly/Function.h>
22 #include <folly/Memory.h>
23 #include <folly/portability/GTest.h>
25 using folly::Function;
28 int func_int_int_add_25(int x) {
31 int func_int_int_add_111(int x) {
34 float floatMult(float a, float b) {
38 template <class T, size_t S>
40 std::array<T, S> data = {{0}};
42 // Two operator() with different argument types.
43 // The InvokeReference tests use both
44 T const& operator()(size_t index) const {
47 T operator()(size_t index, T const& value) {
48 T oldvalue = data[index];
54 template <typename Ret, typename... Args>
55 void deduceArgs(Function<Ret(Args...)>) {}
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 {}
69 // TEST =====================================================================
70 // Test constructibility and non-constructibility for some tricky conversions
72 !std::is_assignable<Function<void()>, CallableButNotCopyable>::value,
75 !std::is_constructible<Function<void()>, CallableButNotCopyable&>::value,
78 !std::is_constructible<Function<void() const>, CallableButNotCopyable>::
82 !std::is_constructible<Function<void() const>, CallableButNotCopyable&>::
87 !std::is_assignable<Function<void()>, CallableButNotCopyable>::value,
90 !std::is_assignable<Function<void()>, CallableButNotCopyable&>::value,
93 !std::is_assignable<Function<void() const>, CallableButNotCopyable>::value,
96 !std::is_assignable<Function<void() const>, CallableButNotCopyable&>::value,
100 std::is_constructible<Function<int(int)>, Function<int(int) const>>::value,
103 !std::is_constructible<Function<int(int) const>, Function<int(int)>>::value,
106 std::is_constructible<Function<int(short)>, Function<short(int) const>>::
110 !std::is_constructible<Function<int(short) const>, Function<short(int)>>::
114 !std::is_constructible<Function<int(int)>, Function<int(int) const>&>::
118 !std::is_constructible<Function<int(int) const>, Function<int(int)>&>::
122 !std::is_constructible<Function<int(short)>, Function<short(int) const>&>::
126 !std::is_constructible<Function<int(short) const>, Function<short(int)>&>::
131 std::is_assignable<Function<int(int)>, Function<int(int) const>>::value,
134 !std::is_assignable<Function<int(int) const>, Function<int(int)>>::value,
137 std::is_assignable<Function<int(short)>, Function<short(int) const>>::value,
140 !std::is_assignable<Function<int(short) const>, Function<short(int)>>::
144 !std::is_assignable<Function<int(int)>, Function<int(int) const>&>::value,
147 !std::is_assignable<Function<int(int) const>, Function<int(int)>&>::value,
150 !std::is_assignable<Function<int(short)>, Function<short(int) const>&>::
154 !std::is_assignable<Function<int(short) const>, Function<short(int)>&>::
159 std::is_nothrow_constructible<
161 Function<int(int) const>>::value,
164 !std::is_nothrow_constructible<
165 Function<int(short)>,
166 Function<short(int) const>>::value,
169 std::is_nothrow_assignable<Function<int(int)>, Function<int(int) const>>::
173 !std::is_nothrow_assignable<
174 Function<int(short)>,
175 Function<short(int) const>>::value,
179 !std::is_constructible<Function<int const&()>, int (*)()>::value,
183 !std::is_constructible<Function<int const&() const>, int (*)()>::value,
186 #if FOLLY_HAVE_NOEXCEPT_FUNCTION_TYPE
188 !std::is_constructible<Function<int const&() noexcept>, int (*)()>::value,
192 !std::is_constructible<Function<int const&() const noexcept>, int (*)()>::
197 // TEST =====================================================================
198 // InvokeFunctor & InvokeReference
200 TEST(Function, InvokeFunctor) {
201 Functor<int, 100> func;
203 sizeof(func) > sizeof(Function<int(size_t)>),
204 "sizeof(Function) is much larger than expected");
207 Function<int(size_t) const> getter = std::move(func);
209 // Function will allocate memory on the heap to store the functor object
210 EXPECT_TRUE(getter.hasAllocatedMemory());
212 EXPECT_EQ(123, getter(5));
215 TEST(Function, InvokeReference) {
216 Functor<int, 10> func;
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);
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));
229 // TEST =====================================================================
232 TEST(Function, Emptiness_T) {
233 Function<int(int)> f;
234 EXPECT_EQ(f, nullptr);
235 EXPECT_EQ(nullptr, f);
237 EXPECT_THROW(f(98), std::bad_function_call);
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));
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));
254 EXPECT_EQ(h, nullptr);
255 EXPECT_EQ(nullptr, h);
257 EXPECT_THROW(h(101), std::bad_function_call);
260 // TEST =====================================================================
263 template <bool UseSwapMethod>
265 Function<int(int)> mf1(func_int_int_add_25);
266 Function<int(int)> mf2(func_int_int_add_111);
268 EXPECT_EQ(125, mf1(100));
269 EXPECT_EQ(211, mf2(100));
277 EXPECT_EQ(125, mf2(100));
278 EXPECT_EQ(211, mf1(100));
280 Function<int(int)> mf3(nullptr);
281 EXPECT_EQ(mf3, nullptr);
289 EXPECT_EQ(211, mf3(100));
290 EXPECT_EQ(nullptr, mf1);
292 Function<int(int)> mf4([](int x) { return x + 222; });
293 EXPECT_EQ(322, mf4(100));
300 EXPECT_EQ(211, mf4(100));
301 EXPECT_EQ(322, mf3(100));
308 EXPECT_EQ(nullptr, mf3);
309 EXPECT_EQ(322, mf1(100));
311 TEST(Function, SwapMethod) {
314 TEST(Function, SwapFunction) {
318 // TEST =====================================================================
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());
331 // TEST =====================================================================
334 TEST(Function, NonCopyableLambda) {
335 auto unique_ptr_int = std::make_unique<int>(900);
336 EXPECT_EQ(900, *unique_ptr_int);
341 (void)fooData; // suppress gcc warning about fooData not being used
343 auto functor = std::bind(
344 [fooData](std::unique_ptr<int>& up) mutable {
348 std::move(unique_ptr_int));
350 EXPECT_EQ(901, functor());
352 Function<int(void)> func = std::move(functor);
353 EXPECT_TRUE(func.hasAllocatedMemory());
355 EXPECT_EQ(902, func());
358 // TEST =====================================================================
361 TEST(Function, OverloadedFunctor) {
362 struct OverloadedFunctor {
364 int operator()(int x) {
368 // variant 2 (const-overload of v1)
369 int operator()(int x) const {
374 int operator()(int x, int) {
378 // variant 4 (const-overload of v3)
379 int operator()(int x, int) const {
383 // variant 5 (non-const, has no const-overload)
384 int operator()(int x, char const*) {
388 // variant 6 (const only)
389 int operator()(int x, std::vector<int> const&) const {
393 OverloadedFunctor of;
395 Function<int(int)> variant1 = of;
396 EXPECT_EQ(100 + 1 * 15, variant1(15));
398 Function<int(int) const> variant2 = of;
399 EXPECT_EQ(100 + 2 * 16, variant2(16));
401 Function<int(int, int)> variant3 = of;
402 EXPECT_EQ(100 + 3 * 17, variant3(17, 0));
404 Function<int(int, int) const> variant4 = of;
405 EXPECT_EQ(100 + 4 * 18, variant4(18, 0));
407 Function<int(int, char const*)> variant5 = of;
408 EXPECT_EQ(100 + 5 * 19, variant5(19, "foo"));
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}));
414 Function<int(int, std::vector<int> const&) const> variant6const = of;
415 EXPECT_EQ(100 + 6 * 21, variant6const(21, {}));
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.
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));
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));
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));
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));
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"));
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, {}));
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, {}));
457 // TEST =====================================================================
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));
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));
469 // Mutable lambda: can only be stored in a const Function:
471 Function<int()> func_mutable = [number]() mutable { return ++number; };
472 EXPECT_EQ(3001, func_mutable());
473 EXPECT_EQ(3002, func_mutable());
475 // test after const-casting
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);
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);
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);
493 // TEST =====================================================================
494 // DataMember & MemberFunction
506 TEST(Function, DataMember) {
508 MemberFunc const& cmf = mf;
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));
521 TEST(Function, MemberFunction) {
523 MemberFunc const& cmf = mf;
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));
535 Function<void(MemberFunc*, int)> setter1 = &MemberFunc::setX;
537 EXPECT_EQ(234, mf.x);
539 Function<void(MemberFunc&, int)> setter2 = &MemberFunc::setX;
541 EXPECT_EQ(345, mf.x);
544 // TEST =====================================================================
545 // CaptureCopyMoveCount & ParameterCopyMoveCount
547 class CopyMoveTracker {
549 struct ConstructorTag {};
551 CopyMoveTracker() = delete;
552 explicit CopyMoveTracker(ConstructorTag)
553 : data_(std::make_shared<std::pair<size_t, size_t>>(0, 0)) {}
555 CopyMoveTracker(CopyMoveTracker const& o) noexcept : data_(o.data_) {
558 CopyMoveTracker& operator=(CopyMoveTracker const& o) noexcept {
564 CopyMoveTracker(CopyMoveTracker&& o) noexcept : data_(o.data_) {
567 CopyMoveTracker& operator=(CopyMoveTracker&& o) noexcept {
573 size_t copyCount() const {
576 size_t moveCount() const {
577 return data_->second;
579 size_t refCount() const {
580 return data_.use_count();
582 void resetCounters() {
583 data_->first = data_->second = 0;
588 std::shared_ptr<std::pair<size_t, size_t>> data_;
591 TEST(Function, CaptureCopyMoveCount) {
592 // This test checks that no unnecessary copies/moves are made.
594 CopyMoveTracker cmt(CopyMoveTracker::ConstructorTag{});
595 EXPECT_EQ(0, cmt.copyCount());
596 EXPECT_EQ(0, cmt.moveCount());
597 EXPECT_EQ(1, cmt.refCount());
599 // Move into lambda, move lambda into Function
600 auto lambda1 = [cmt = std::move(cmt)]() {
601 return cmt.moveCount();
603 Function<size_t(void)> uf1 = std::move(lambda1);
605 // Max copies: 0. Max copy+moves: 2.
606 EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 3);
607 EXPECT_LE(cmt.copyCount(), 0);
611 // Move into lambda, copy lambda into Function
612 auto lambda2 = [cmt = std::move(cmt)]() {
613 return cmt.moveCount();
615 Function<size_t(void)> uf2 = lambda2;
617 // Max copies: 1. Max copy+moves: 2.
618 EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 3);
619 EXPECT_LE(cmt.copyCount(), 1);
621 // Invoking Function must not make copies/moves of the callable
625 EXPECT_EQ(0, cmt.copyCount());
626 EXPECT_EQ(0, cmt.moveCount());
629 TEST(Function, ParameterCopyMoveCount) {
630 // This test checks that no unnecessary copies/moves are made.
632 CopyMoveTracker cmt(CopyMoveTracker::ConstructorTag{});
633 EXPECT_EQ(0, cmt.copyCount());
634 EXPECT_EQ(0, cmt.moveCount());
635 EXPECT_EQ(1, cmt.refCount());
638 Function<size_t(CopyMoveTracker)> uf1 = [](CopyMoveTracker c) {
639 return c.moveCount();
644 // Max copies: 1. Max copy+moves: 2.
645 EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
646 EXPECT_LE(cmt.copyCount(), 1);
650 // Max copies: 1. Max copy+moves: 2.
651 EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 2);
652 EXPECT_LE(cmt.copyCount(), 0);
655 Function<size_t(CopyMoveTracker&)> uf2 = [](CopyMoveTracker& c) {
656 return c.moveCount();
661 // Max copies: 0. Max copy+moves: 0.
662 EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 0);
663 EXPECT_LE(cmt.copyCount(), 0);
665 // pass by const reference
666 Function<size_t(CopyMoveTracker const&)> uf3 = [](CopyMoveTracker const& c) {
667 return c.moveCount();
672 // Max copies: 0. Max copy+moves: 0.
673 EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 0);
674 EXPECT_LE(cmt.copyCount(), 0);
676 // pass by rvalue reference
677 Function<size_t(CopyMoveTracker &&)> uf4 = [](CopyMoveTracker&& c) {
678 return c.moveCount();
683 // Max copies: 0. Max copy+moves: 0.
684 EXPECT_LE(cmt.moveCount() + cmt.copyCount(), 0);
685 EXPECT_LE(cmt.copyCount(), 0);
688 // TEST =====================================================================
689 // VariadicTemplate & VariadicArguments
691 struct VariadicTemplateSum {
692 int operator()() const {
695 template <class... Args>
696 int operator()(int x, Args... args) const {
697 return x + (*this)(args...);
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();
706 EXPECT_EQ(66, uf1(66));
707 EXPECT_EQ(99, uf2(55, 44));
708 EXPECT_EQ(66, uf3(33, 22, 11));
711 struct VariadicArgumentsSum {
712 int operator()(int count, ...) const {
715 va_start(args, count);
716 for (int i = 0; i < count; ++i) {
717 result += va_arg(args, int);
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();
729 EXPECT_EQ(0, uf1(0));
730 EXPECT_EQ(66, uf2(1, 66));
731 EXPECT_EQ(99, uf3(2, 55, 44));
734 // TEST =====================================================================
735 // SafeCaptureByReference
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&).
744 template <typename T>
747 Function<void(typename T::value_type const&) const> const& func) {
748 for (auto const& elem : range) {
753 TEST(Function, SafeCaptureByReference) {
754 std::vector<int> const vec = {20, 30, 40, 2, 3, 4, 200, 300, 400};
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; });
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; });
770 // TEST =====================================================================
773 TEST(Function, IgnoreReturnValue) {
776 // Assign a lambda that return int to a folly::Function that returns void.
777 Function<void()> f = [&]() -> int { return ++x; };
783 Function<int()> g = [&]() -> int { return ++x; };
784 Function<void()> cg = std::move(g);
791 // TEST =====================================================================
792 // ReturnConvertible, ConvertReturnType
794 TEST(Function, ReturnConvertible) {
798 struct CDerived : CBase {};
800 Function<double()> f1 = []() -> int { return 5; };
801 EXPECT_EQ(5.0, f1());
803 Function<int()> f2 = []() -> double { return 5.2; };
809 Function<CBase const&()> f3 = [&]() -> CDerived const& { return derived; };
810 EXPECT_EQ(55, f3().x);
812 Function<CBase const&()> f4 = [&]() -> CDerived& { return derived; };
813 EXPECT_EQ(55, f4().x);
815 Function<CBase&()> f5 = [&]() -> CDerived& { return derived; };
816 EXPECT_EQ(55, f5().x);
818 Function<CBase const*()> f6 = [&]() -> CDerived const* { return &derived; };
819 EXPECT_EQ(f6()->x, 55);
821 Function<CBase const*()> f7 = [&]() -> CDerived* { return &derived; };
822 EXPECT_EQ(55, f7()->x);
824 Function<CBase*()> f8 = [&]() -> CDerived* { return &derived; };
825 EXPECT_EQ(55, f8()->x);
827 Function<CBase()> f9 = [&]() -> CDerived {
832 EXPECT_EQ(66, f9().x);
835 TEST(Function, ConvertReturnType) {
839 struct CDerived : CBase {};
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());
847 Function<double()> f2 = []() -> double { return 5.2; };
848 Function<int()> cf2 = std::move(f2);
850 Function<double()> ccf2 = std::move(cf2);
851 EXPECT_EQ(5.0, ccf2());
856 Function<CDerived const&()> f3 = [&]() -> CDerived const& { return derived; };
857 Function<CBase const&()> cf3 = std::move(f3);
858 EXPECT_EQ(55, cf3().x);
860 Function<CDerived&()> f4 = [&]() -> CDerived& { return derived; };
861 Function<CBase const&()> cf4 = std::move(f4);
862 EXPECT_EQ(55, cf4().x);
864 Function<CDerived&()> f5 = [&]() -> CDerived& { return derived; };
865 Function<CBase&()> cf5 = std::move(f5);
866 EXPECT_EQ(55, cf5().x);
868 Function<CDerived const*()> f6 = [&]() -> CDerived const* {
871 Function<CBase const*()> cf6 = std::move(f6);
872 EXPECT_EQ(55, cf6()->x);
874 Function<CDerived const*()> f7 = [&]() -> CDerived* { return &derived; };
875 Function<CBase const*()> cf7 = std::move(f7);
876 EXPECT_EQ(55, cf7()->x);
878 Function<CDerived*()> f8 = [&]() -> CDerived* { return &derived; };
879 Function<CBase*()> cf8 = std::move(f8);
880 EXPECT_EQ(55, cf8()->x);
882 Function<CDerived()> f9 = [&]() -> CDerived {
887 Function<CBase()> cf9 = std::move(f9);
888 EXPECT_EQ(66, cf9().x);
891 // TEST =====================================================================
894 TEST(Function, asStdFunction_void) {
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");
904 TEST(Function, asStdFunction_void_const) {
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");
914 TEST(Function, asStdFunction_return) {
916 folly::Function<int()> f = [&] {
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");
927 TEST(Function, asStdFunction_return_const) {
929 folly::Function<int() const> f = [&] {
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");
940 TEST(Function, asStdFunction_args) {
942 folly::Function<void(int, int)> f = [&](int x, int y) {
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");
953 TEST(Function, asStdFunction_args_const) {
955 folly::Function<void(int, int) const> f = [&](int x, int y) {
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");
966 // TEST =====================================================================
969 TEST(Function, asSharedProxy_void) {
971 folly::Function<void()> f = [&i] { ++i; };
972 auto sp = std::move(f).asSharedProxy();
980 TEST(Function, asSharedProxy_void_const) {
982 folly::Function<void() const> f = [&i] { ++i; };
983 auto sp = std::move(f).asSharedProxy();
991 TEST(Function, asSharedProxy_return) {
992 folly::Function<int()> f = [i = 0]() mutable {
996 auto sp = std::move(f).asSharedProxy();
999 EXPECT_EQ(2, spcopy());
1002 TEST(Function, asSharedProxy_return_const) {
1004 folly::Function<int() const> f = [&i] {
1008 auto sp = std::move(f).asSharedProxy();
1011 EXPECT_EQ(2, spcopy());
1014 TEST(Function, asSharedProxy_args) {
1016 folly::Function<int(int, int)> f = [&](int x, int y) mutable {
1020 auto sp = std::move(f).asSharedProxy();
1022 EXPECT_EQ(120, sp(100, 10));
1024 EXPECT_EQ(120, spcopy(100, 10));
1028 TEST(Function, asSharedProxy_args_const) {
1030 folly::Function<int(int, int) const> f = [&i](int x, int y) {
1032 return x * 100 + y * 10 + i;
1034 auto sp = std::move(f).asSharedProxy();
1036 EXPECT_EQ(561, sp(5, 6));
1037 EXPECT_EQ(562, spcopy(5, 6));
1040 TEST(Function, NoAllocatedMemoryAfterMove) {
1041 Functor<int, 100> foo;
1043 Function<int(size_t)> func = foo;
1044 EXPECT_TRUE(func.hasAllocatedMemory());
1046 Function<int(size_t)> func2 = std::move(func);
1047 EXPECT_TRUE(func2.hasAllocatedMemory());
1048 EXPECT_FALSE(func.hasAllocatedMemory());
1051 TEST(Function, ConstCastEmbedded) {
1053 auto functor = [&x]() { ++x; };
1055 Function<void() const> func(functor);
1056 EXPECT_FALSE(func.hasAllocatedMemory());
1058 Function<void()> func2(std::move(func));
1059 EXPECT_FALSE(func2.hasAllocatedMemory());
1062 TEST(Function, EmptyAfterConstCast) {
1063 Function<int(size_t)> func;
1066 Function<int(size_t) const> func2 = constCastFunction(std::move(func));
1067 EXPECT_FALSE(func2);
1070 TEST(Function, SelfStdSwap) {
1071 Function<int()> f = [] { return 42; };
1073 EXPECT_TRUE(bool(f));
1076 EXPECT_TRUE(bool(f));
1079 EXPECT_TRUE(bool(f));
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));
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; }});
1099 TEST(Function, CtorWithCopy) {
1102 X(X const&) noexcept(true) {}
1103 X& operator=(X const&) = default;
1107 Y(Y const&) noexcept(false) {}
1108 Y(Y&&) noexcept(true) {}
1109 Y& operator=(Y&&) = default;
1110 Y& operator=(Y const&) = default;
1112 auto lx = [x = X()]{};
1113 auto ly = [y = Y()]{};
1114 EXPECT_TRUE(noexcept(Function<void()>(lx)));
1115 EXPECT_FALSE(noexcept(Function<void()>(ly)));
1118 TEST(Function, Bug_T23346238) {
1119 const Function<void()> nullfun;