Chromium Code Reviews| 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 public: | |
| 724 using DeleteCounterPtr = T; | |
|
Nico
2016/01/21 17:29:14
is this used for anything?
dcheng
2016/01/21 19:15:33
Done.
| |
| 725 }; | |
| 726 | |
| 727 struct CustomDeleter { | |
| 728 void operator()(DeleteCounter* c) { delete c; } | |
| 729 }; | |
| 730 | |
| 731 using MoveOnlyTypesToTest = | |
| 732 ::testing::Types<scoped_ptr<DeleteCounter>, | |
| 733 std::unique_ptr<DeleteCounter>, | |
| 734 std::unique_ptr<DeleteCounter, CustomDeleter>>; | |
| 735 TYPED_TEST_CASE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest); | |
| 736 | |
| 737 TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) { | |
| 722 int deletes = 0; | 738 int deletes = 0; |
| 723 | 739 |
| 724 // Tests the Passed() function's support for pointers. | 740 TypeParam ptr(new DeleteCounter(&deletes)); |
| 725 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); | 741 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()); | 742 EXPECT_FALSE(ptr.get()); |
| 729 EXPECT_EQ(0, deletes); | 743 EXPECT_EQ(0, deletes); |
| 730 | 744 |
| 731 // If we never invoke the Callback, it retains ownership and deletes. | 745 // If we never invoke the Callback, it retains ownership and deletes. |
| 732 unused_callback.Reset(); | 746 callback.Reset(); |
| 733 EXPECT_EQ(1, deletes); | 747 EXPECT_EQ(1, deletes); |
| 748 } | |
| 734 | 749 |
| 735 // Tests the Passed() function's support for rvalues. | 750 TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) { |
| 736 deletes = 0; | 751 int deletes = 0; |
| 737 DeleteCounter* counter = new DeleteCounter(&deletes); | 752 Callback<TypeParam()> callback = Bind( |
| 738 Callback<scoped_ptr<DeleteCounter>()> callback = | 753 &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); | 754 EXPECT_EQ(0, deletes); |
| 743 | 755 |
| 744 // Check that ownership can be transferred back out. | 756 // If we never invoke the Callback, it retains ownership and deletes. |
| 745 scoped_ptr<DeleteCounter> result = callback.Run(); | 757 callback.Reset(); |
| 758 EXPECT_EQ(1, deletes); | |
| 759 } | |
| 760 | |
| 761 // Check that ownership can be transferred back out. | |
| 762 TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) { | |
| 763 int deletes = 0; | |
| 764 DeleteCounter* counter = new DeleteCounter(&deletes); | |
| 765 Callback<TypeParam()> callback = | |
| 766 Bind(&PassThru<TypeParam>, Passed(TypeParam(counter))); | |
| 767 TypeParam result = callback.Run(); | |
| 746 ASSERT_EQ(counter, result.get()); | 768 ASSERT_EQ(counter, result.get()); |
| 747 EXPECT_EQ(0, deletes); | 769 EXPECT_EQ(0, deletes); |
| 748 | 770 |
| 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. | 771 // Resetting does not delete since ownership was transferred. |
| 793 callback.Reset(); | 772 callback.Reset(); |
| 794 EXPECT_EQ(0, deletes); | 773 EXPECT_EQ(0, deletes); |
| 795 | 774 |
| 796 // Ensure that we actually did get ownership. | 775 // Ensure that we actually did get ownership. |
| 797 result.reset(); | 776 result.reset(); |
| 798 EXPECT_EQ(1, deletes); | 777 EXPECT_EQ(1, deletes); |
| 778 } | |
| 799 | 779 |
| 780 TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) { | |
| 781 int deletes = 0; | |
| 782 TypeParam ptr(new DeleteCounter(&deletes)); | |
| 800 // Test unbound argument forwarding. | 783 // Test unbound argument forwarding. |
| 801 Callback<std::unique_ptr<DeleteCounter>(std::unique_ptr<DeleteCounter>)> | 784 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)); | 785 cb_unbound.Run(std::move(ptr)); |
| 786 EXPECT_EQ(1, deletes); | |
| 805 } | 787 } |
| 806 | 788 |
| 807 // Argument Copy-constructor usage for non-reference parameters. | 789 // Argument Copy-constructor usage for non-reference parameters. |
| 808 // - Bound arguments are only copied once. | 790 // - Bound arguments are only copied once. |
| 809 // - Forwarded arguments are only copied once. | 791 // - Forwarded arguments are only copied once. |
| 810 // - Forwarded arguments with coercions are only copied twice (once for the | 792 // - Forwarded arguments with coercions are only copied twice (once for the |
| 811 // coercion, and one for the final dispatch). | 793 // coercion, and one for the final dispatch). |
| 812 TEST_F(BindTest, ArgumentCopies) { | 794 TEST_F(BindTest, ArgumentCopies) { |
| 813 int copies = 0; | 795 int copies = 0; |
| 814 int assigns = 0; | 796 int assigns = 0; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 872 base::Callback<void(int)> null_cb; | 854 base::Callback<void(int)> null_cb; |
| 873 ASSERT_TRUE(null_cb.is_null()); | 855 ASSERT_TRUE(null_cb.is_null()); |
| 874 EXPECT_DEATH(base::Bind(null_cb, 42), ""); | 856 EXPECT_DEATH(base::Bind(null_cb, 42), ""); |
| 875 } | 857 } |
| 876 | 858 |
| 877 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && | 859 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && |
| 878 // GTEST_HAS_DEATH_TEST | 860 // GTEST_HAS_DEATH_TEST |
| 879 | 861 |
| 880 } // namespace | 862 } // namespace |
| 881 } // namespace base | 863 } // namespace base |
| OLD | NEW |