OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 deletes = 0; | 705 deletes = 0; |
706 counter = new DeleteCounter(&deletes); | 706 counter = new DeleteCounter(&deletes); |
707 base::Closure own_object_cb = | 707 base::Closure own_object_cb = |
708 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); | 708 Bind(&DeleteCounter::VoidMethod0, Owned(counter)); |
709 own_object_cb.Run(); | 709 own_object_cb.Run(); |
710 EXPECT_EQ(0, deletes); | 710 EXPECT_EQ(0, deletes); |
711 own_object_cb.Reset(); | 711 own_object_cb.Reset(); |
712 EXPECT_EQ(1, deletes); | 712 EXPECT_EQ(1, deletes); |
713 } | 713 } |
714 | 714 |
715 // Passed() wrapper support. | 715 // Tests for Passed() wrapper support: |
716 // - Passed() can be constructed from a pointer to scoper. | 716 // - Passed() can be constructed from a pointer to scoper. |
717 // - Passed() can be constructed from a scoper rvalue. | 717 // - Passed() can be constructed from a scoper rvalue. |
718 // - Using Passed() gives Callback Ownership. | 718 // - Using Passed() gives Callback Ownership. |
719 // - Ownership is transferred from Callback to callee on the first Run(). | 719 // - Ownership is transferred from Callback to callee on the first Run(). |
720 // - Callback supports unbound arguments. | 720 // - Callback supports unbound arguments. |
721 TEST_F(BindTest, ScopedPtr) { | 721 template <typename T> |
| 722 class BindMoveOnlyTypeTest : public ::testing::Test { |
| 723 }; |
| 724 |
| 725 struct CustomDeleter { |
| 726 void operator()(DeleteCounter* c) { delete c; } |
| 727 }; |
| 728 |
| 729 using MoveOnlyTypesToTest = |
| 730 ::testing::Types<scoped_ptr<DeleteCounter>, |
| 731 std::unique_ptr<DeleteCounter>, |
| 732 std::unique_ptr<DeleteCounter, CustomDeleter>>; |
| 733 TYPED_TEST_CASE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest); |
| 734 |
| 735 TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) { |
722 int deletes = 0; | 736 int deletes = 0; |
723 | 737 |
724 // Tests the Passed() function's support for pointers. | 738 TypeParam ptr(new DeleteCounter(&deletes)); |
725 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); | 739 Callback<TypeParam()> callback = Bind(&PassThru<TypeParam>, Passed(&ptr)); |
726 Callback<scoped_ptr<DeleteCounter>()> unused_callback = | |
727 Bind(&PassThru<scoped_ptr<DeleteCounter> >, Passed(&ptr)); | |
728 EXPECT_FALSE(ptr.get()); | 740 EXPECT_FALSE(ptr.get()); |
729 EXPECT_EQ(0, deletes); | 741 EXPECT_EQ(0, deletes); |
730 | 742 |
731 // If we never invoke the Callback, it retains ownership and deletes. | 743 // If we never invoke the Callback, it retains ownership and deletes. |
732 unused_callback.Reset(); | 744 callback.Reset(); |
733 EXPECT_EQ(1, deletes); | 745 EXPECT_EQ(1, deletes); |
| 746 } |
734 | 747 |
735 // Tests the Passed() function's support for rvalues. | 748 TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) { |
736 deletes = 0; | 749 int deletes = 0; |
737 DeleteCounter* counter = new DeleteCounter(&deletes); | 750 Callback<TypeParam()> callback = Bind( |
738 Callback<scoped_ptr<DeleteCounter>()> callback = | 751 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes)))); |
739 Bind(&PassThru<scoped_ptr<DeleteCounter> >, | |
740 Passed(scoped_ptr<DeleteCounter>(counter))); | |
741 EXPECT_FALSE(ptr.get()); | |
742 EXPECT_EQ(0, deletes); | 752 EXPECT_EQ(0, deletes); |
743 | 753 |
744 // Check that ownership can be transferred back out. | 754 // If we never invoke the Callback, it retains ownership and deletes. |
745 scoped_ptr<DeleteCounter> result = callback.Run(); | 755 callback.Reset(); |
| 756 EXPECT_EQ(1, deletes); |
| 757 } |
| 758 |
| 759 // Check that ownership can be transferred back out. |
| 760 TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) { |
| 761 int deletes = 0; |
| 762 DeleteCounter* counter = new DeleteCounter(&deletes); |
| 763 Callback<TypeParam()> callback = |
| 764 Bind(&PassThru<TypeParam>, Passed(TypeParam(counter))); |
| 765 TypeParam result = callback.Run(); |
746 ASSERT_EQ(counter, result.get()); | 766 ASSERT_EQ(counter, result.get()); |
747 EXPECT_EQ(0, deletes); | 767 EXPECT_EQ(0, deletes); |
748 | 768 |
749 // Resetting does not delete since ownership was transferred. | |
750 callback.Reset(); | |
751 EXPECT_EQ(0, deletes); | |
752 | |
753 // Ensure that we actually did get ownership. | |
754 result.reset(); | |
755 EXPECT_EQ(1, deletes); | |
756 | |
757 // Test unbound argument forwarding. | |
758 Callback<scoped_ptr<DeleteCounter>(scoped_ptr<DeleteCounter>)> cb_unbound = | |
759 Bind(&PassThru<scoped_ptr<DeleteCounter> >); | |
760 ptr.reset(new DeleteCounter(&deletes)); | |
761 cb_unbound.Run(std::move(ptr)); | |
762 } | |
763 | |
764 TEST_F(BindTest, UniquePtr) { | |
765 int deletes = 0; | |
766 | |
767 // Tests the Passed() function's support for pointers. | |
768 std::unique_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); | |
769 Callback<std::unique_ptr<DeleteCounter>()> unused_callback = | |
770 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, Passed(&ptr)); | |
771 EXPECT_FALSE(ptr.get()); | |
772 EXPECT_EQ(0, deletes); | |
773 | |
774 // If we never invoke the Callback, it retains ownership and deletes. | |
775 unused_callback.Reset(); | |
776 EXPECT_EQ(1, deletes); | |
777 | |
778 // Tests the Passed() function's support for rvalues. | |
779 deletes = 0; | |
780 DeleteCounter* counter = new DeleteCounter(&deletes); | |
781 Callback<std::unique_ptr<DeleteCounter>()> callback = | |
782 Bind(&PassThru<std::unique_ptr<DeleteCounter>>, | |
783 Passed(std::unique_ptr<DeleteCounter>(counter))); | |
784 EXPECT_FALSE(ptr.get()); | |
785 EXPECT_EQ(0, deletes); | |
786 | |
787 // Check that ownership can be transferred back out. | |
788 std::unique_ptr<DeleteCounter> result = callback.Run(); | |
789 ASSERT_EQ(counter, result.get()); | |
790 EXPECT_EQ(0, deletes); | |
791 | |
792 // Resetting does not delete since ownership was transferred. | 769 // Resetting does not delete since ownership was transferred. |
793 callback.Reset(); | 770 callback.Reset(); |
794 EXPECT_EQ(0, deletes); | 771 EXPECT_EQ(0, deletes); |
795 | 772 |
796 // Ensure that we actually did get ownership. | 773 // Ensure that we actually did get ownership. |
797 result.reset(); | 774 result.reset(); |
798 EXPECT_EQ(1, deletes); | 775 EXPECT_EQ(1, deletes); |
| 776 } |
799 | 777 |
| 778 TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) { |
| 779 int deletes = 0; |
| 780 TypeParam ptr(new DeleteCounter(&deletes)); |
800 // Test unbound argument forwarding. | 781 // Test unbound argument forwarding. |
801 Callback<std::unique_ptr<DeleteCounter>(std::unique_ptr<DeleteCounter>)> | 782 Callback<TypeParam(TypeParam)> cb_unbound = Bind(&PassThru<TypeParam>); |
802 cb_unbound = Bind(&PassThru<std::unique_ptr<DeleteCounter>>); | |
803 ptr.reset(new DeleteCounter(&deletes)); | |
804 cb_unbound.Run(std::move(ptr)); | 783 cb_unbound.Run(std::move(ptr)); |
| 784 EXPECT_EQ(1, deletes); |
805 } | 785 } |
806 | 786 |
807 // Argument Copy-constructor usage for non-reference parameters. | 787 // Argument Copy-constructor usage for non-reference parameters. |
808 // - Bound arguments are only copied once. | 788 // - Bound arguments are only copied once. |
809 // - Forwarded arguments are only copied once. | 789 // - Forwarded arguments are only copied once. |
810 // - Forwarded arguments with coercions are only copied twice (once for the | 790 // - Forwarded arguments with coercions are only copied twice (once for the |
811 // coercion, and one for the final dispatch). | 791 // coercion, and one for the final dispatch). |
812 TEST_F(BindTest, ArgumentCopies) { | 792 TEST_F(BindTest, ArgumentCopies) { |
813 int copies = 0; | 793 int copies = 0; |
814 int assigns = 0; | 794 int assigns = 0; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 base::Callback<void(int)> null_cb; | 852 base::Callback<void(int)> null_cb; |
873 ASSERT_TRUE(null_cb.is_null()); | 853 ASSERT_TRUE(null_cb.is_null()); |
874 EXPECT_DEATH(base::Bind(null_cb, 42), ""); | 854 EXPECT_DEATH(base::Bind(null_cb, 42), ""); |
875 } | 855 } |
876 | 856 |
877 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && | 857 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && |
878 // GTEST_HAS_DEATH_TEST | 858 // GTEST_HAS_DEATH_TEST |
879 | 859 |
880 } // namespace | 860 } // namespace |
881 } // namespace base | 861 } // namespace base |
OLD | NEW |