| 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 |