1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/test/bind_test_util.h"
18 #include "base/test/gtest_util.h"
19 #include "build/build_config.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 using ::testing::AnyNumber;
24 using ::testing::ByMove;
25 using ::testing::Mock;
26 using ::testing::Return;
27 using ::testing::StrictMock;
39 MOCK_METHOD0(VoidMethod0, void());
40 MOCK_CONST_METHOD0(VoidConstMethod0, void());
42 MOCK_METHOD0(IntMethod0, int());
43 MOCK_CONST_METHOD0(IntConstMethod0, int());
45 MOCK_METHOD1(VoidMethodWithIntArg, void(int));
46 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
49 // Particularly important in this test to ensure no copies are made.
50 DISALLOW_COPY_AND_ASSIGN(NoRef);
53 class HasRef : public NoRef {
57 MOCK_CONST_METHOD0(AddRef, void());
58 MOCK_CONST_METHOD0(Release, bool());
59 MOCK_CONST_METHOD0(HasAtLeastOneRef, bool());
62 // Particularly important in this test to ensure no copies are made.
63 DISALLOW_COPY_AND_ASSIGN(HasRef);
66 class HasRefPrivateDtor : public HasRef {
68 ~HasRefPrivateDtor() = default;
71 static const int kParentValue = 1;
72 static const int kChildValue = 2;
76 void AddRef() const {}
77 void Release() const {}
78 bool HasAtLeastOneRef() const { return true; }
79 virtual void VirtualSet() { value = kParentValue; }
80 void NonVirtualSet() { value = kParentValue; }
84 class Child : public Parent {
86 void VirtualSet() override { value = kChildValue; }
87 void NonVirtualSet() { value = kChildValue; }
92 virtual void VirtualSet() { value = kParentValue; }
93 void NonVirtualSet() { value = kParentValue; }
97 class NoRefChild : public NoRefParent {
98 void VirtualSet() override { value = kChildValue; }
99 void NonVirtualSet() { value = kChildValue; }
102 // Used for probing the number of copies and moves that occur if a type must be
103 // coerced during argument forwarding in the Run() methods.
104 struct DerivedCopyMoveCounter {
105 DerivedCopyMoveCounter(int* copies,
107 int* move_constructs,
111 move_constructs_(move_constructs),
112 move_assigns_(move_assigns) {}
115 int* move_constructs_;
119 // Used for probing the number of copies and moves in an argument.
120 class CopyMoveCounter {
122 CopyMoveCounter(int* copies,
124 int* move_constructs,
128 move_constructs_(move_constructs),
129 move_assigns_(move_assigns) {}
131 CopyMoveCounter(const CopyMoveCounter& other)
132 : copies_(other.copies_),
133 assigns_(other.assigns_),
134 move_constructs_(other.move_constructs_),
135 move_assigns_(other.move_assigns_) {
139 CopyMoveCounter(CopyMoveCounter&& other)
140 : copies_(other.copies_),
141 assigns_(other.assigns_),
142 move_constructs_(other.move_constructs_),
143 move_assigns_(other.move_assigns_) {
144 (*move_constructs_)++;
147 // Probing for copies from coercion.
148 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
149 : copies_(other.copies_),
150 assigns_(other.assigns_),
151 move_constructs_(other.move_constructs_),
152 move_assigns_(other.move_assigns_) {
156 // Probing for moves from coercion.
157 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
158 : copies_(other.copies_),
159 assigns_(other.assigns_),
160 move_constructs_(other.move_constructs_),
161 move_assigns_(other.move_assigns_) {
162 (*move_constructs_)++;
165 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
166 copies_ = rhs.copies_;
167 assigns_ = rhs.assigns_;
168 move_constructs_ = rhs.move_constructs_;
169 move_assigns_ = rhs.move_assigns_;
176 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
177 copies_ = rhs.copies_;
178 assigns_ = rhs.assigns_;
179 move_constructs_ = rhs.move_constructs_;
180 move_assigns_ = rhs.move_assigns_;
194 int* move_constructs_;
198 // Used for probing the number of copies in an argument. The instance is a
199 // copyable and non-movable type.
202 CopyCounter(int* copies, int* assigns)
203 : counter_(copies, assigns, nullptr, nullptr) {}
204 CopyCounter(const CopyCounter& other) = default;
205 CopyCounter& operator=(const CopyCounter& other) = default;
207 explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {}
209 int copies() const { return counter_.copies(); }
212 CopyMoveCounter counter_;
215 // Used for probing the number of moves in an argument. The instance is a
216 // non-copyable and movable type.
219 MoveCounter(int* move_constructs, int* move_assigns)
220 : counter_(nullptr, nullptr, move_constructs, move_assigns) {}
221 MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {}
222 MoveCounter& operator=(MoveCounter&& other) {
223 counter_ = std::move(other.counter_);
227 explicit MoveCounter(DerivedCopyMoveCounter&& other)
228 : counter_(std::move(other)) {}
231 CopyMoveCounter counter_;
234 class DeleteCounter {
236 explicit DeleteCounter(int* deletes)
237 : deletes_(deletes) {
244 void VoidMethod0() {}
250 template <typename T>
251 T PassThru(T scoper) {
255 // Some test functions that we can Bind to.
256 template <typename T>
257 T PolymorphicIdentity(T t) {
261 template <typename... Ts>
262 struct VoidPolymorphic {
263 static void Run(Ts... t) {}
266 int Identity(int n) {
270 int ArrayGet(const int array[], int n) {
274 int Sum(int a, int b, int c, int d, int e, int f) {
275 return a + b + c + d + e + f;
278 const char* CStringIdentity(const char* s) {
282 int GetCopies(const CopyMoveCounter& counter) {
283 return counter.copies();
286 int UnwrapNoRefParent(NoRefParent p) {
290 int UnwrapNoRefParentPtr(NoRefParent* p) {
294 int UnwrapNoRefParentConstRef(const NoRefParent& p) {
298 void RefArgSet(int &n) {
302 void PtrArgSet(int *n) {
306 int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
310 int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
314 void TakesACallback(const RepeatingClosure& callback) {
318 int Noexcept() noexcept {
322 class BindTest : public ::testing::Test {
325 const_has_ref_ptr_ = &has_ref_;
326 const_no_ref_ptr_ = &no_ref_;
327 static_func_mock_ptr = &static_func_mock_;
330 ~BindTest() override = default;
332 static void VoidFunc0() {
333 static_func_mock_ptr->VoidMethod0();
336 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
337 int NoexceptMethod() noexcept { return 42; }
338 int ConstNoexceptMethod() const noexcept { return 42; }
341 StrictMock<NoRef> no_ref_;
342 StrictMock<HasRef> has_ref_;
343 const HasRef* const_has_ref_ptr_;
344 const NoRef* const_no_ref_ptr_;
345 StrictMock<NoRef> static_func_mock_;
347 // Used by the static functions to perform expectations.
348 static StrictMock<NoRef>* static_func_mock_ptr;
351 DISALLOW_COPY_AND_ASSIGN(BindTest);
354 StrictMock<NoRef>* BindTest::static_func_mock_ptr;
355 StrictMock<NoRef>* g_func_mock_ptr;
358 g_func_mock_ptr->VoidMethod0();
362 return g_func_mock_ptr->IntMethod0();
365 TEST_F(BindTest, BasicTest) {
366 RepeatingCallback<int(int, int, int)> cb = BindRepeating(&Sum, 32, 16, 8);
367 EXPECT_EQ(92, cb.Run(13, 12, 11));
369 RepeatingCallback<int(int, int, int, int, int, int)> c1 = BindRepeating(&Sum);
370 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
372 RepeatingCallback<int(int, int, int)> c2 = BindRepeating(c1, 32, 16, 8);
373 EXPECT_EQ(86, c2.Run(11, 10, 9));
375 RepeatingCallback<int()> c3 = BindRepeating(c2, 4, 2, 1);
376 EXPECT_EQ(63, c3.Run());
379 // Test that currying the rvalue result of another BindRepeating() works
381 // - rvalue should be usable as argument to BindRepeating().
382 // - multiple runs of resulting RepeatingCallback remain valid.
383 TEST_F(BindTest, CurryingRvalueResultOfBind) {
385 RepeatingClosure cb = BindRepeating(&TakesACallback,
386 BindRepeating(&PtrArgSet, &n));
388 // If we implement BindRepeating() such that the return value has
389 // auto_ptr-like semantics, the second call here will fail because ownership
390 // of the internal BindState<> would have been transferred to a *temporary*
391 // construction of a RepeatingCallback object on the first call.
400 TEST_F(BindTest, RepeatingCallbackBasicTest) {
401 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
403 // RepeatingCallback can run via a lvalue-reference.
404 EXPECT_EQ(63, c0.Run(32));
406 // It is valid to call a RepeatingCallback more than once.
407 EXPECT_EQ(54, c0.Run(23));
409 // BindRepeating can handle a RepeatingCallback as the target functor.
410 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
412 // RepeatingCallback can run via a rvalue-reference.
413 EXPECT_EQ(42, std::move(c1).Run());
415 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
416 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
419 TEST_F(BindTest, OnceCallbackBasicTest) {
420 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
422 // OnceCallback can run via a rvalue-reference.
423 EXPECT_EQ(63, std::move(c0).Run(32));
425 // After running via the rvalue-reference, the value of the OnceCallback
426 // is undefined. The implementation simply clears the instance after the
428 EXPECT_TRUE(c0.is_null());
430 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
432 // BindOnce can handle a rvalue-reference of OnceCallback as the target
434 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
435 EXPECT_EQ(41, std::move(c1).Run());
437 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
438 EXPECT_EQ(41, BindOnce(c2, 13).Run());
441 // IgnoreResult adapter test.
442 // - Function with return value.
443 // - Method with return value.
444 // - Const Method with return.
445 // - Method with return value bound to WeakPtr<>.
446 // - Const Method with return bound to WeakPtr<>.
447 TEST_F(BindTest, IgnoreResultForRepeating) {
448 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
449 EXPECT_CALL(has_ref_, AddRef()).Times(2);
450 EXPECT_CALL(has_ref_, Release()).Times(2);
451 EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
452 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
453 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
454 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
455 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
457 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
458 normal_func_cb.Run();
460 RepeatingClosure non_void_method_cb =
461 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
462 non_void_method_cb.Run();
464 RepeatingClosure non_void_const_method_cb =
465 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
466 non_void_const_method_cb.Run();
468 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
469 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
471 RepeatingClosure non_void_weak_method_cb =
472 BindRepeating(IgnoreResult(&NoRef::IntMethod0),
473 weak_factory.GetWeakPtr());
474 non_void_weak_method_cb.Run();
476 RepeatingClosure non_void_weak_const_method_cb =
477 BindRepeating(IgnoreResult(&NoRef::IntConstMethod0),
478 weak_factory.GetWeakPtr());
479 non_void_weak_const_method_cb.Run();
481 weak_factory.InvalidateWeakPtrs();
482 non_void_weak_const_method_cb.Run();
483 non_void_weak_method_cb.Run();
486 TEST_F(BindTest, IgnoreResultForOnce) {
487 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
488 EXPECT_CALL(has_ref_, AddRef()).Times(2);
489 EXPECT_CALL(has_ref_, Release()).Times(2);
490 EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
491 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
492 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
494 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
495 std::move(normal_func_cb).Run();
497 OnceClosure non_void_method_cb =
498 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
499 std::move(non_void_method_cb).Run();
501 OnceClosure non_void_const_method_cb =
502 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
503 std::move(non_void_const_method_cb).Run();
505 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
506 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
508 OnceClosure non_void_weak_method_cb =
509 BindOnce(IgnoreResult(&NoRef::IntMethod0),
510 weak_factory.GetWeakPtr());
511 OnceClosure non_void_weak_const_method_cb =
512 BindOnce(IgnoreResult(&NoRef::IntConstMethod0),
513 weak_factory.GetWeakPtr());
515 weak_factory.InvalidateWeakPtrs();
516 std::move(non_void_weak_const_method_cb).Run();
517 std::move(non_void_weak_method_cb).Run();
520 // Functions that take reference parameters.
521 // - Forced reference parameter type still stores a copy.
522 // - Forced const reference parameter type still stores a copy.
523 TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
526 const int& const_ref_n = n;
528 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
529 EXPECT_EQ(n, ref_copies_cb.Run());
531 EXPECT_EQ(n - 1, ref_copies_cb.Run());
533 RepeatingCallback<int()> const_ref_copies_cb =
534 BindRepeating(&Identity, const_ref_n);
535 EXPECT_EQ(n, const_ref_copies_cb.Run());
537 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
540 TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
543 const int& const_ref_n = n;
545 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
547 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
549 OnceCallback<int()> const_ref_copies_cb =
550 BindOnce(&Identity, const_ref_n);
552 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
555 // Check that we can pass in arrays and have them be stored as a pointer.
556 // - Array of values stores a pointer.
557 // - Array of const values stores a pointer.
558 TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
559 int array[4] = {1, 1, 1, 1};
560 const int (*const_array_ptr)[4] = &array;
562 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
563 EXPECT_EQ(1, array_cb.Run());
565 RepeatingCallback<int()> const_array_cb =
566 BindRepeating(&ArrayGet, *const_array_ptr, 1);
567 EXPECT_EQ(1, const_array_cb.Run());
570 EXPECT_EQ(3, array_cb.Run());
571 EXPECT_EQ(3, const_array_cb.Run());
574 TEST_F(BindTest, ArrayArgumentBindingForOnce) {
575 int array[4] = {1, 1, 1, 1};
576 const int (*const_array_ptr)[4] = &array;
578 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
579 OnceCallback<int()> const_array_cb =
580 BindOnce(&ArrayGet, *const_array_ptr, 1);
583 EXPECT_EQ(3, std::move(array_cb).Run());
584 EXPECT_EQ(3, std::move(const_array_cb).Run());
587 // WeakPtr() support.
588 // - Method bound to WeakPtr<> to non-const object.
589 // - Const method bound to WeakPtr<> to non-const object.
590 // - Const method bound to WeakPtr<> to const object.
591 // - Normal Function with WeakPtr<> as P1 can have return type and is
593 TEST_F(BindTest, WeakPtrForRepeating) {
594 EXPECT_CALL(no_ref_, VoidMethod0());
595 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
597 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
598 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
600 RepeatingClosure method_cb =
601 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
604 RepeatingClosure const_method_cb =
605 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
606 const_method_cb.Run();
608 RepeatingClosure const_method_const_ptr_cb =
609 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
610 const_method_const_ptr_cb.Run();
612 RepeatingCallback<int(int)> normal_func_cb =
613 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
614 EXPECT_EQ(1, normal_func_cb.Run(1));
616 weak_factory.InvalidateWeakPtrs();
617 const_weak_factory.InvalidateWeakPtrs();
620 const_method_cb.Run();
621 const_method_const_ptr_cb.Run();
623 // Still runs even after the pointers are invalidated.
624 EXPECT_EQ(2, normal_func_cb.Run(2));
627 TEST_F(BindTest, WeakPtrForOnce) {
628 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
629 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
631 OnceClosure method_cb =
632 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
633 OnceClosure const_method_cb =
634 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
635 OnceClosure const_method_const_ptr_cb =
636 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
637 OnceCallback<int(int)> normal_func_cb =
638 BindOnce(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
640 weak_factory.InvalidateWeakPtrs();
641 const_weak_factory.InvalidateWeakPtrs();
643 std::move(method_cb).Run();
644 std::move(const_method_cb).Run();
645 std::move(const_method_const_ptr_cb).Run();
647 // Still runs even after the pointers are invalidated.
648 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
651 // std::cref() wrapper support.
652 // - Binding w/o std::cref takes a copy.
653 // - Binding a std::cref takes a reference.
654 // - Binding std::cref to a function std::cref does not copy on invoke.
655 TEST_F(BindTest, StdCrefForRepeating) {
658 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
659 RepeatingCallback<int()> const_ref_cb =
660 BindRepeating(&Identity, std::cref(n));
661 EXPECT_EQ(n, copy_cb.Run());
662 EXPECT_EQ(n, const_ref_cb.Run());
664 EXPECT_EQ(n - 1, copy_cb.Run());
665 EXPECT_EQ(n, const_ref_cb.Run());
669 int move_constructs = 0;
670 int move_assigns = 0;
671 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
672 RepeatingCallback<int()> all_const_ref_cb =
673 BindRepeating(&GetCopies, std::cref(counter));
674 EXPECT_EQ(0, all_const_ref_cb.Run());
675 EXPECT_EQ(0, copies);
676 EXPECT_EQ(0, assigns);
677 EXPECT_EQ(0, move_constructs);
678 EXPECT_EQ(0, move_assigns);
681 TEST_F(BindTest, StdCrefForOnce) {
684 OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
685 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, std::cref(n));
687 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
688 EXPECT_EQ(n, std::move(const_ref_cb).Run());
692 int move_constructs = 0;
693 int move_assigns = 0;
694 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
695 OnceCallback<int()> all_const_ref_cb =
696 BindOnce(&GetCopies, std::cref(counter));
697 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
698 EXPECT_EQ(0, copies);
699 EXPECT_EQ(0, assigns);
700 EXPECT_EQ(0, move_constructs);
701 EXPECT_EQ(0, move_assigns);
704 // Test Owned() support.
705 TEST_F(BindTest, OwnedForRepeatingRawPtr) {
707 DeleteCounter* counter = new DeleteCounter(&deletes);
709 // If we don't capture, delete happens on Callback destruction/reset.
710 // return the same value.
711 RepeatingCallback<DeleteCounter*()> no_capture_cb =
712 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
713 ASSERT_EQ(counter, no_capture_cb.Run());
714 ASSERT_EQ(counter, no_capture_cb.Run());
715 EXPECT_EQ(0, deletes);
716 no_capture_cb.Reset(); // This should trigger a delete.
717 EXPECT_EQ(1, deletes);
720 counter = new DeleteCounter(&deletes);
721 RepeatingClosure own_object_cb =
722 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
724 EXPECT_EQ(0, deletes);
725 own_object_cb.Reset();
726 EXPECT_EQ(1, deletes);
729 TEST_F(BindTest, OwnedForOnceRawPtr) {
731 DeleteCounter* counter = new DeleteCounter(&deletes);
733 // If we don't capture, delete happens on Callback destruction/reset.
734 // return the same value.
735 OnceCallback<DeleteCounter*()> no_capture_cb =
736 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
737 EXPECT_EQ(0, deletes);
738 no_capture_cb.Reset(); // This should trigger a delete.
739 EXPECT_EQ(1, deletes);
742 counter = new DeleteCounter(&deletes);
743 OnceClosure own_object_cb =
744 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
745 EXPECT_EQ(0, deletes);
746 own_object_cb.Reset();
747 EXPECT_EQ(1, deletes);
750 TEST_F(BindTest, OwnedForRepeatingUniquePtr) {
752 auto counter = std::make_unique<DeleteCounter>(&deletes);
753 DeleteCounter* raw_counter = counter.get();
755 // If we don't capture, delete happens on Callback destruction/reset.
756 // return the same value.
757 RepeatingCallback<DeleteCounter*()> no_capture_cb = BindRepeating(
758 &PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
759 ASSERT_EQ(raw_counter, no_capture_cb.Run());
760 ASSERT_EQ(raw_counter, no_capture_cb.Run());
761 EXPECT_EQ(0, deletes);
762 no_capture_cb.Reset(); // This should trigger a delete.
763 EXPECT_EQ(1, deletes);
766 counter = std::make_unique<DeleteCounter>(&deletes);
767 RepeatingClosure own_object_cb =
768 BindRepeating(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
770 EXPECT_EQ(0, deletes);
771 own_object_cb.Reset();
772 EXPECT_EQ(1, deletes);
775 TEST_F(BindTest, OwnedForOnceUniquePtr) {
777 auto counter = std::make_unique<DeleteCounter>(&deletes);
779 // If we don't capture, delete happens on Callback destruction/reset.
780 // return the same value.
781 OnceCallback<DeleteCounter*()> no_capture_cb =
782 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
783 EXPECT_EQ(0, deletes);
784 no_capture_cb.Reset(); // This should trigger a delete.
785 EXPECT_EQ(1, deletes);
788 counter = std::make_unique<DeleteCounter>(&deletes);
789 OnceClosure own_object_cb =
790 BindOnce(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
791 EXPECT_EQ(0, deletes);
792 own_object_cb.Reset();
793 EXPECT_EQ(1, deletes);
796 template <typename T>
797 class BindVariantsTest : public ::testing::Test {
800 struct RepeatingTestConfig {
801 template <typename Signature>
802 using CallbackType = RepeatingCallback<Signature>;
803 using ClosureType = RepeatingClosure;
805 template <typename F, typename... Args>
806 static CallbackType<MakeUnboundRunType<F, Args...>>
807 Bind(F&& f, Args&&... args) {
808 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
812 struct OnceTestConfig {
813 template <typename Signature>
814 using CallbackType = OnceCallback<Signature>;
815 using ClosureType = OnceClosure;
817 template <typename F, typename... Args>
818 static CallbackType<MakeUnboundRunType<F, Args...>>
819 Bind(F&& f, Args&&... args) {
820 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
824 using BindVariantsTestConfig = ::testing::Types<
825 RepeatingTestConfig, OnceTestConfig>;
826 TYPED_TEST_SUITE(BindVariantsTest, BindVariantsTestConfig);
828 template <typename TypeParam, typename Signature>
829 using CallbackType = typename TypeParam::template CallbackType<Signature>;
831 // Function type support.
832 // - Normal function.
833 // - Normal function bound with non-refcounted first argument.
834 // - Method bound to non-const object.
835 // - Method bound to scoped_refptr.
836 // - Const method bound to non-const object.
837 // - Const method bound to const object.
838 // - Derived classes can be used with pointers to non-virtual base functions.
839 // - Derived classes can be used with pointers to virtual base functions (and
840 // preserve virtual dispatch).
841 TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
842 using ClosureType = typename TypeParam::ClosureType;
844 StrictMock<HasRef> has_ref;
845 StrictMock<NoRef> no_ref;
846 StrictMock<NoRef> static_func_mock;
847 const HasRef* const_has_ref_ptr = &has_ref;
848 g_func_mock_ptr = &static_func_mock;
850 EXPECT_CALL(static_func_mock, VoidMethod0());
851 EXPECT_CALL(has_ref, AddRef()).Times(4);
852 EXPECT_CALL(has_ref, Release()).Times(4);
853 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
854 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
855 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
857 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
858 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
859 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
860 std::move(normal_cb).Run();
861 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
863 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
864 ClosureType method_refptr_cb =
865 TypeParam::Bind(&HasRef::VoidMethod0, WrapRefCounted(&has_ref));
866 ClosureType const_method_nonconst_obj_cb =
867 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
868 ClosureType const_method_const_obj_cb =
869 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
870 std::move(method_cb).Run();
871 std::move(method_refptr_cb).Run();
872 std::move(const_method_nonconst_obj_cb).Run();
873 std::move(const_method_const_obj_cb).Run();
877 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
878 std::move(virtual_set_cb).Run();
879 EXPECT_EQ(kChildValue, child.value);
882 ClosureType non_virtual_set_cb =
883 TypeParam::Bind(&Parent::NonVirtualSet, &child);
884 std::move(non_virtual_set_cb).Run();
885 EXPECT_EQ(kParentValue, child.value);
888 // Return value support.
889 // - Function with return value.
890 // - Method with return value.
891 // - Const method with return value.
892 // - Move-only return value.
893 TYPED_TEST(BindVariantsTest, ReturnValues) {
894 StrictMock<NoRef> static_func_mock;
895 StrictMock<HasRef> has_ref;
896 g_func_mock_ptr = &static_func_mock;
897 const HasRef* const_has_ref_ptr = &has_ref;
899 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
900 EXPECT_CALL(has_ref, AddRef()).Times(4);
901 EXPECT_CALL(has_ref, Release()).Times(4);
902 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
903 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
904 EXPECT_CALL(has_ref, IntConstMethod0())
905 .WillOnce(Return(41337))
906 .WillOnce(Return(51337));
907 EXPECT_CALL(has_ref, UniquePtrMethod0())
908 .WillOnce(Return(ByMove(std::make_unique<int>(42))));
910 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
911 CallbackType<TypeParam, int()> method_cb =
912 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
913 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
914 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
915 CallbackType<TypeParam, int()> const_method_const_obj_cb =
916 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
917 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
918 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
919 EXPECT_EQ(1337, std::move(normal_cb).Run());
920 EXPECT_EQ(31337, std::move(method_cb).Run());
921 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
922 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
923 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
926 // Argument binding tests.
927 // - Argument binding to primitive.
928 // - Argument binding to primitive pointer.
929 // - Argument binding to a literal integer.
930 // - Argument binding to a literal string.
931 // - Argument binding with template function.
932 // - Argument binding to an object.
933 // - Argument binding to pointer to incomplete type.
934 // - Argument gets type converted.
935 // - Pointer argument gets converted.
936 // - Const Reference forces conversion.
937 TYPED_TEST(BindVariantsTest, ArgumentBinding) {
940 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
941 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
942 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
943 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
944 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
948 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
950 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
951 EXPECT_EQ(incomplete_ptr,
952 TypeParam::Bind(&PolymorphicIdentity<IncompleteType*>,
953 incomplete_ptr).Run());
957 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
960 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
963 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
966 // Unbound argument type support tests.
968 // - Unbound pointer.
969 // - Unbound reference.
970 // - Unbound const reference.
971 // - Unbound unsized array.
972 // - Unbound sized array.
973 // - Unbound array-of-arrays.
974 TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
975 CallbackType<TypeParam, void(int)> unbound_value_cb =
976 TypeParam::Bind(&VoidPolymorphic<int>::Run);
977 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
978 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
979 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
980 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
981 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
982 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
983 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
984 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
985 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
986 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
987 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
988 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
989 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
990 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
993 // Function with unbound reference parameter.
994 // - Original parameter is modified by callback.
995 TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
997 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
998 TypeParam::Bind(&RefArgSet);
999 std::move(unbound_ref_cb).Run(n);
1003 // Unretained() wrapper support.
1004 // - Method bound to Unretained() non-const object.
1005 // - Const method bound to Unretained() non-const object.
1006 // - Const method bound to Unretained() const object.
1007 TYPED_TEST(BindVariantsTest, Unretained) {
1008 StrictMock<NoRef> no_ref;
1009 const NoRef* const_no_ref_ptr = &no_ref;
1011 EXPECT_CALL(no_ref, VoidMethod0());
1012 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
1014 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
1015 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
1016 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
1019 TYPED_TEST(BindVariantsTest, ScopedRefptr) {
1020 StrictMock<HasRef> has_ref;
1021 EXPECT_CALL(has_ref, AddRef()).Times(1);
1022 EXPECT_CALL(has_ref, Release()).Times(1);
1023 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1025 const scoped_refptr<HasRef> refptr(&has_ref);
1026 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb = TypeParam::Bind(
1027 &FunctionWithScopedRefptrFirstParam, std::cref(refptr), 1);
1028 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
1031 TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
1032 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
1033 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
1034 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
1037 // Tests for Passed() wrapper support:
1038 // - Passed() can be constructed from a pointer to scoper.
1039 // - Passed() can be constructed from a scoper rvalue.
1040 // - Using Passed() gives Callback Ownership.
1041 // - Ownership is transferred from Callback to callee on the first Run().
1042 // - Callback supports unbound arguments.
1043 template <typename T>
1044 class BindMoveOnlyTypeTest : public ::testing::Test {
1047 struct CustomDeleter {
1048 void operator()(DeleteCounter* c) { delete c; }
1051 using MoveOnlyTypesToTest =
1052 ::testing::Types<std::unique_ptr<DeleteCounter>,
1053 std::unique_ptr<DeleteCounter, CustomDeleter>>;
1054 TYPED_TEST_SUITE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
1056 TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
1059 TypeParam ptr(new DeleteCounter(&deletes));
1060 RepeatingCallback<TypeParam()> callback =
1061 BindRepeating(&PassThru<TypeParam>, Passed(&ptr));
1062 EXPECT_FALSE(ptr.get());
1063 EXPECT_EQ(0, deletes);
1065 // If we never invoke the Callback, it retains ownership and deletes.
1067 EXPECT_EQ(1, deletes);
1070 TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
1072 RepeatingCallback<TypeParam()> callback = BindRepeating(
1073 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
1074 EXPECT_EQ(0, deletes);
1076 // If we never invoke the Callback, it retains ownership and deletes.
1078 EXPECT_EQ(1, deletes);
1081 // Check that ownership can be transferred back out.
1082 TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
1084 DeleteCounter* counter = new DeleteCounter(&deletes);
1085 RepeatingCallback<TypeParam()> callback =
1086 BindRepeating(&PassThru<TypeParam>, Passed(TypeParam(counter)));
1087 TypeParam result = callback.Run();
1088 ASSERT_EQ(counter, result.get());
1089 EXPECT_EQ(0, deletes);
1091 // Resetting does not delete since ownership was transferred.
1093 EXPECT_EQ(0, deletes);
1095 // Ensure that we actually did get ownership.
1097 EXPECT_EQ(1, deletes);
1100 TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
1102 TypeParam ptr(new DeleteCounter(&deletes));
1103 // Test unbound argument forwarding.
1104 RepeatingCallback<TypeParam(TypeParam)> cb_unbound =
1105 BindRepeating(&PassThru<TypeParam>);
1106 cb_unbound.Run(std::move(ptr));
1107 EXPECT_EQ(1, deletes);
1110 void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
1111 ASSERT_EQ(1u, v.size());
1112 EXPECT_EQ(12345, *v[0]);
1115 std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
1116 std::vector<std::unique_ptr<int>> v) {
1121 // Test that a vector containing move-only types can be used with Callback.
1122 TEST_F(BindTest, BindMoveOnlyVector) {
1123 using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
1126 v.push_back(std::make_unique<int>(12345));
1128 // Early binding should work:
1129 base::RepeatingCallback<MoveOnlyVector()> bound_cb =
1130 base::BindRepeating(&AcceptAndReturnMoveOnlyVector, Passed(&v));
1131 MoveOnlyVector intermediate_result = bound_cb.Run();
1132 VerifyVector(intermediate_result);
1134 // As should passing it as an argument to Run():
1135 base::RepeatingCallback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
1136 base::BindRepeating(&AcceptAndReturnMoveOnlyVector);
1137 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
1138 VerifyVector(final_result);
1141 // Argument copy-constructor usage for non-reference copy-only parameters.
1142 // - Bound arguments are only copied once.
1143 // - Forwarded arguments are only copied once.
1144 // - Forwarded arguments with coercions are only copied twice (once for the
1145 // coercion, and one for the final dispatch).
1146 TEST_F(BindTest, ArgumentCopies) {
1150 CopyCounter counter(&copies, &assigns);
1151 Bind(&VoidPolymorphic<CopyCounter>::Run, counter);
1152 EXPECT_EQ(1, copies);
1153 EXPECT_EQ(0, assigns);
1157 Bind(&VoidPolymorphic<CopyCounter>::Run, CopyCounter(&copies, &assigns));
1158 EXPECT_EQ(1, copies);
1159 EXPECT_EQ(0, assigns);
1163 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
1164 EXPECT_EQ(2, copies);
1165 EXPECT_EQ(0, assigns);
1169 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(&copies, &assigns));
1170 EXPECT_EQ(1, copies);
1171 EXPECT_EQ(0, assigns);
1175 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
1176 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
1177 EXPECT_EQ(2, copies);
1178 EXPECT_EQ(0, assigns);
1182 Bind(&VoidPolymorphic<CopyCounter>::Run)
1184 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
1185 EXPECT_EQ(2, copies);
1186 EXPECT_EQ(0, assigns);
1189 // Argument move-constructor usage for move-only parameters.
1190 // - Bound arguments passed by move are not copied.
1191 TEST_F(BindTest, ArgumentMoves) {
1192 int move_constructs = 0;
1193 int move_assigns = 0;
1195 Bind(&VoidPolymorphic<const MoveCounter&>::Run,
1196 MoveCounter(&move_constructs, &move_assigns));
1197 EXPECT_EQ(1, move_constructs);
1198 EXPECT_EQ(0, move_assigns);
1200 // TODO(tzik): Support binding move-only type into a non-reference parameter
1201 // of a variant of Callback.
1203 move_constructs = 0;
1205 Bind(&VoidPolymorphic<MoveCounter>::Run)
1206 .Run(MoveCounter(&move_constructs, &move_assigns));
1207 EXPECT_EQ(1, move_constructs);
1208 EXPECT_EQ(0, move_assigns);
1210 move_constructs = 0;
1212 Bind(&VoidPolymorphic<MoveCounter>::Run)
1213 .Run(MoveCounter(DerivedCopyMoveCounter(
1214 nullptr, nullptr, &move_constructs, &move_assigns)));
1215 EXPECT_EQ(2, move_constructs);
1216 EXPECT_EQ(0, move_assigns);
1219 // Argument constructor usage for non-reference movable-copyable
1221 // - Bound arguments passed by move are not copied.
1222 // - Forwarded arguments are only copied once.
1223 // - Forwarded arguments with coercions are only copied once and moved once.
1224 TEST_F(BindTest, ArgumentCopiesAndMoves) {
1227 int move_constructs = 0;
1228 int move_assigns = 0;
1230 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
1231 Bind(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
1232 EXPECT_EQ(1, copies);
1233 EXPECT_EQ(0, assigns);
1234 EXPECT_EQ(0, move_constructs);
1235 EXPECT_EQ(0, move_assigns);
1239 move_constructs = 0;
1241 Bind(&VoidPolymorphic<CopyMoveCounter>::Run,
1242 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1243 EXPECT_EQ(0, copies);
1244 EXPECT_EQ(0, assigns);
1245 EXPECT_EQ(1, move_constructs);
1246 EXPECT_EQ(0, move_assigns);
1250 move_constructs = 0;
1252 Bind(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter);
1253 EXPECT_EQ(1, copies);
1254 EXPECT_EQ(0, assigns);
1255 EXPECT_EQ(1, move_constructs);
1256 EXPECT_EQ(0, move_assigns);
1260 move_constructs = 0;
1262 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1263 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1264 EXPECT_EQ(0, copies);
1265 EXPECT_EQ(0, assigns);
1266 EXPECT_EQ(1, move_constructs);
1267 EXPECT_EQ(0, move_assigns);
1269 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1273 move_constructs = 0;
1275 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1276 .Run(CopyMoveCounter(derived_counter));
1277 EXPECT_EQ(1, copies);
1278 EXPECT_EQ(0, assigns);
1279 EXPECT_EQ(1, move_constructs);
1280 EXPECT_EQ(0, move_assigns);
1284 move_constructs = 0;
1286 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1287 .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1288 &copies, &assigns, &move_constructs, &move_assigns)));
1289 EXPECT_EQ(0, copies);
1290 EXPECT_EQ(0, assigns);
1291 EXPECT_EQ(2, move_constructs);
1292 EXPECT_EQ(0, move_assigns);
1295 TEST_F(BindTest, CapturelessLambda) {
1296 EXPECT_FALSE(internal::IsCallableObject<void>::value);
1297 EXPECT_FALSE(internal::IsCallableObject<int>::value);
1298 EXPECT_FALSE(internal::IsCallableObject<void (*)()>::value);
1299 EXPECT_FALSE(internal::IsCallableObject<void (NoRef::*)()>::value);
1302 EXPECT_TRUE(internal::IsCallableObject<decltype(f)>::value);
1305 auto g = [i]() { (void)i; };
1306 EXPECT_TRUE(internal::IsCallableObject<decltype(g)>::value);
1308 auto h = [](int, double) { return 'k'; };
1309 EXPECT_TRUE((std::is_same<
1311 internal::ExtractCallableRunType<decltype(h)>>::value));
1313 EXPECT_EQ(42, Bind([] { return 42; }).Run());
1314 EXPECT_EQ(42, Bind([](int i) { return i * 7; }, 6).Run());
1317 base::RepeatingCallback<void(int)> cb =
1318 BindRepeating([](int* x, int i) { *x *= i; }, Unretained(&x));
1325 TEST_F(BindTest, EmptyFunctor) {
1326 struct NonEmptyFunctor {
1327 int operator()() const { return x; }
1331 struct EmptyFunctor {
1332 int operator()() { return 42; }
1335 struct EmptyFunctorConst {
1336 int operator()() const { return 42; }
1339 EXPECT_TRUE(internal::IsCallableObject<NonEmptyFunctor>::value);
1340 EXPECT_TRUE(internal::IsCallableObject<EmptyFunctor>::value);
1341 EXPECT_TRUE(internal::IsCallableObject<EmptyFunctorConst>::value);
1342 EXPECT_EQ(42, BindOnce(EmptyFunctor()).Run());
1343 EXPECT_EQ(42, BindOnce(EmptyFunctorConst()).Run());
1344 EXPECT_EQ(42, BindRepeating(EmptyFunctorConst()).Run());
1347 TEST_F(BindTest, CapturingLambdaForTesting) {
1348 // Test copyable lambdas.
1350 EXPECT_EQ(42, BindLambdaForTesting([=](int y) { return x * y; }).Run(7));
1352 BindLambdaForTesting([=](int y) mutable { return x *= y; }).Run(7));
1353 auto f = [x](std::unique_ptr<int> y) { return x * *y; };
1354 EXPECT_EQ(42, BindLambdaForTesting(f).Run(std::make_unique<int>(7)));
1356 // Test move-only lambdas.
1357 auto y = std::make_unique<int>(7);
1358 auto g = [y = std::move(y)](int& x) mutable {
1359 return x * *std::exchange(y, nullptr);
1361 EXPECT_EQ(42, BindLambdaForTesting(std::move(g)).Run(x));
1363 y = std::make_unique<int>(7);
1364 auto h = [x, y = std::move(y)] { return x * *y; };
1365 EXPECT_EQ(42, BindLambdaForTesting(std::move(h)).Run());
1368 TEST_F(BindTest, Cancellation) {
1369 EXPECT_CALL(no_ref_, VoidMethodWithIntArg(_)).Times(2);
1371 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
1372 RepeatingCallback<void(int)> cb =
1373 BindRepeating(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1374 RepeatingClosure cb2 = BindRepeating(cb, 8);
1375 OnceClosure cb3 = BindOnce(cb, 8);
1377 OnceCallback<void(int)> cb4 =
1378 BindOnce(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1379 EXPECT_FALSE(cb4.IsCancelled());
1381 OnceClosure cb5 = BindOnce(std::move(cb4), 8);
1383 EXPECT_FALSE(cb.IsCancelled());
1384 EXPECT_FALSE(cb2.IsCancelled());
1385 EXPECT_FALSE(cb3.IsCancelled());
1386 EXPECT_FALSE(cb5.IsCancelled());
1391 weak_factory.InvalidateWeakPtrs();
1393 EXPECT_TRUE(cb.IsCancelled());
1394 EXPECT_TRUE(cb2.IsCancelled());
1395 EXPECT_TRUE(cb3.IsCancelled());
1396 EXPECT_TRUE(cb5.IsCancelled());
1400 std::move(cb3).Run();
1401 std::move(cb5).Run();
1404 TEST_F(BindTest, OnceCallback) {
1405 // Check if Callback variants have declarations of conversions as expected.
1406 // Copy constructor and assignment of RepeatingCallback.
1407 static_assert(std::is_constructible<
1408 RepeatingClosure, const RepeatingClosure&>::value,
1409 "RepeatingClosure should be copyable.");
1411 std::is_assignable<RepeatingClosure, const RepeatingClosure&>::value,
1412 "RepeatingClosure should be copy-assignable.");
1414 // Move constructor and assignment of RepeatingCallback.
1415 static_assert(std::is_constructible<
1416 RepeatingClosure, RepeatingClosure&&>::value,
1417 "RepeatingClosure should be movable.");
1418 static_assert(std::is_assignable<RepeatingClosure, RepeatingClosure&&>::value,
1419 "RepeatingClosure should be move-assignable");
1421 // Conversions from OnceCallback to RepeatingCallback.
1422 static_assert(!std::is_constructible<
1423 RepeatingClosure, const OnceClosure&>::value,
1424 "OnceClosure should not be convertible to RepeatingClosure.");
1426 !std::is_assignable<RepeatingClosure, const OnceClosure&>::value,
1427 "OnceClosure should not be convertible to RepeatingClosure.");
1429 // Destructive conversions from OnceCallback to RepeatingCallback.
1430 static_assert(!std::is_constructible<
1431 RepeatingClosure, OnceClosure&&>::value,
1432 "OnceClosure should not be convertible to RepeatingClosure.");
1433 static_assert(!std::is_assignable<RepeatingClosure, OnceClosure&&>::value,
1434 "OnceClosure should not be convertible to RepeatingClosure.");
1436 // Copy constructor and assignment of OnceCallback.
1437 static_assert(!std::is_constructible<
1438 OnceClosure, const OnceClosure&>::value,
1439 "OnceClosure should not be copyable.");
1440 static_assert(!std::is_assignable<OnceClosure, const OnceClosure&>::value,
1441 "OnceClosure should not be copy-assignable");
1443 // Move constructor and assignment of OnceCallback.
1444 static_assert(std::is_constructible<
1445 OnceClosure, OnceClosure&&>::value,
1446 "OnceClosure should be movable.");
1447 static_assert(std::is_assignable<OnceClosure, OnceClosure&&>::value,
1448 "OnceClosure should be move-assignable.");
1450 // Conversions from RepeatingCallback to OnceCallback.
1451 static_assert(std::is_constructible<
1452 OnceClosure, const RepeatingClosure&>::value,
1453 "RepeatingClosure should be convertible to OnceClosure.");
1454 static_assert(std::is_assignable<OnceClosure, const RepeatingClosure&>::value,
1455 "RepeatingClosure should be convertible to OnceClosure.");
1457 // Destructive conversions from RepeatingCallback to OnceCallback.
1458 static_assert(std::is_constructible<
1459 OnceClosure, RepeatingClosure&&>::value,
1460 "RepeatingClosure should be convertible to OnceClosure.");
1461 static_assert(std::is_assignable<OnceClosure, RepeatingClosure&&>::value,
1462 "RepeatingClosure should be covretible to OnceClosure.");
1464 OnceClosure cb = BindOnce(&VoidPolymorphic<>::Run);
1465 std::move(cb).Run();
1467 // RepeatingCallback should be convertible to OnceCallback.
1468 OnceClosure cb2 = BindRepeating(&VoidPolymorphic<>::Run);
1469 std::move(cb2).Run();
1471 RepeatingClosure cb3 = BindRepeating(&VoidPolymorphic<>::Run);
1473 std::move(cb).Run();
1475 cb = std::move(cb2);
1477 OnceCallback<void(int)> cb4 =
1478 BindOnce(&VoidPolymorphic<std::unique_ptr<int>, int>::Run,
1479 std::make_unique<int>(0));
1480 BindOnce(std::move(cb4), 1).Run();
1483 // Callback construction and assignment tests.
1484 // - Construction from an InvokerStorageHolder should not cause ref/deref.
1485 // - Assignment from other callback should only cause one ref
1487 // TODO(ajwong): Is there actually a way to test this?
1490 int __fastcall FastCallFunc(int n) {
1494 int __stdcall StdCallFunc(int n) {
1498 // Windows specific calling convention support.
1499 // - Can bind a __fastcall function.
1500 // - Can bind a __stdcall function.
1501 // - Can bind const and non-const __stdcall methods.
1502 TEST_F(BindTest, WindowsCallingConventions) {
1503 auto fastcall_cb = BindRepeating(&FastCallFunc, 1);
1504 EXPECT_EQ(1, fastcall_cb.Run());
1506 auto stdcall_cb = BindRepeating(&StdCallFunc, 2);
1507 EXPECT_EQ(2, stdcall_cb.Run());
1509 class MethodHolder {
1511 int __stdcall Func(int n) { return n; }
1512 int __stdcall ConstFunc(int n) const { return -n; }
1516 auto stdcall_method_cb =
1517 BindRepeating(&MethodHolder::Func, base::Unretained(&obj), 1);
1518 EXPECT_EQ(1, stdcall_method_cb.Run());
1520 const MethodHolder const_obj;
1521 auto stdcall_const_method_cb =
1522 BindRepeating(&MethodHolder::ConstFunc, base::Unretained(&const_obj), 1);
1523 EXPECT_EQ(-1, stdcall_const_method_cb.Run());
1527 // Test unwrapping the various wrapping functions.
1529 TEST_F(BindTest, UnwrapUnretained) {
1531 auto unretained = Unretained(&i);
1532 EXPECT_EQ(&i, internal::Unwrap(unretained));
1533 EXPECT_EQ(&i, internal::Unwrap(std::move(unretained)));
1536 TEST_F(BindTest, UnwrapConstRef) {
1538 auto const_ref = std::cref(p);
1539 EXPECT_EQ(&p, &internal::Unwrap(const_ref));
1540 EXPECT_EQ(&p, &internal::Unwrap(std::move(const_ref)));
1543 TEST_F(BindTest, UnwrapRetainedRef) {
1544 auto p = MakeRefCounted<RefCountedData<int>>();
1545 auto retained_ref = RetainedRef(p);
1546 EXPECT_EQ(p.get(), internal::Unwrap(retained_ref));
1547 EXPECT_EQ(p.get(), internal::Unwrap(std::move(retained_ref)));
1550 TEST_F(BindTest, UnwrapOwned) {
1553 auto owned = Owned(p);
1554 EXPECT_EQ(p, internal::Unwrap(owned));
1555 EXPECT_EQ(p, internal::Unwrap(std::move(owned)));
1559 auto p = std::make_unique<int>();
1560 int* raw_p = p.get();
1561 auto owned = Owned(std::move(p));
1562 EXPECT_EQ(raw_p, internal::Unwrap(owned));
1563 EXPECT_EQ(raw_p, internal::Unwrap(std::move(owned)));
1567 TEST_F(BindTest, UnwrapPassed) {
1569 auto passed = Passed(WrapUnique(p));
1570 EXPECT_EQ(p, internal::Unwrap(passed).get());
1573 EXPECT_EQ(p, internal::Unwrap(Passed(WrapUnique(p))).get());
1576 TEST_F(BindTest, BindNoexcept) {
1577 EXPECT_EQ(42, base::BindOnce(&Noexcept).Run());
1580 base::BindOnce(&BindTest::NoexceptMethod, base::Unretained(this)).Run());
1582 42, base::BindOnce(&BindTest::ConstNoexceptMethod, base::Unretained(this))
1586 // Test null callbacks cause a DCHECK.
1587 TEST(BindDeathTest, NullCallback) {
1588 base::RepeatingCallback<void(int)> null_cb;
1589 ASSERT_TRUE(null_cb.is_null());
1590 EXPECT_CHECK_DEATH(base::BindRepeating(null_cb, 42));
1593 TEST(BindDeathTest, NullFunctionPointer) {
1594 void (*null_function)(int) = nullptr;
1595 EXPECT_DCHECK_DEATH(base::BindRepeating(null_function, 42));
1598 TEST(BindDeathTest, NullCallbackWithoutBoundArgs) {
1599 base::OnceCallback<void(int)> null_cb;
1600 ASSERT_TRUE(null_cb.is_null());
1601 EXPECT_CHECK_DEATH(base::BindOnce(std::move(null_cb)));
1604 TEST(BindDeathTest, BanFirstOwnerOfRefCountedType) {
1605 StrictMock<HasRef> has_ref;
1606 EXPECT_DCHECK_DEATH({
1607 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillOnce(Return(false));
1608 base::BindOnce(&HasRef::VoidMethod0, &has_ref);