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 "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 143 } |
144 | 144 |
145 void VoidMethod0() {} | 145 void VoidMethod0() {} |
146 | 146 |
147 private: | 147 private: |
148 int* deletes_; | 148 int* deletes_; |
149 }; | 149 }; |
150 | 150 |
151 template <typename T> | 151 template <typename T> |
152 T PassThru(T scoper) { | 152 T PassThru(T scoper) { |
153 return scoper.Pass(); | 153 return scoper; |
154 } | 154 } |
155 | 155 |
156 // Some test functions that we can Bind to. | 156 // Some test functions that we can Bind to. |
157 template <typename T> | 157 template <typename T> |
158 T PolymorphicIdentity(T t) { | 158 T PolymorphicIdentity(T t) { |
159 return t; | 159 return t; |
160 } | 160 } |
161 | 161 |
162 template <typename T> | 162 template <typename T> |
163 void VoidPolymorphic1(T t) { | 163 void VoidPolymorphic1(T t) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 // - Normal function bound with non-refcounted first argument. | 320 // - Normal function bound with non-refcounted first argument. |
321 // - Method bound to non-const object. | 321 // - Method bound to non-const object. |
322 // - Method bound to scoped_refptr. | 322 // - Method bound to scoped_refptr. |
323 // - Const method bound to non-const object. | 323 // - Const method bound to non-const object. |
324 // - Const method bound to const object. | 324 // - Const method bound to const object. |
325 // - Derived classes can be used with pointers to non-virtual base functions. | 325 // - Derived classes can be used with pointers to non-virtual base functions. |
326 // - Derived classes can be used with pointers to virtual base functions (and | 326 // - Derived classes can be used with pointers to virtual base functions (and |
327 // preserve virtual dispatch). | 327 // preserve virtual dispatch). |
328 TEST_F(BindTest, FunctionTypeSupport) { | 328 TEST_F(BindTest, FunctionTypeSupport) { |
329 EXPECT_CALL(static_func_mock_, VoidMethod0()); | 329 EXPECT_CALL(static_func_mock_, VoidMethod0()); |
330 EXPECT_CALL(has_ref_, AddRef()).Times(5); | 330 EXPECT_CALL(has_ref_, AddRef()).Times(4); |
331 EXPECT_CALL(has_ref_, Release()).Times(5); | 331 EXPECT_CALL(has_ref_, Release()).Times(4); |
332 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2); | 332 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2); |
333 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2); | 333 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2); |
334 | 334 |
335 Closure normal_cb = Bind(&VoidFunc0); | 335 Closure normal_cb = Bind(&VoidFunc0); |
336 Callback<NoRef*(void)> normal_non_refcounted_cb = | 336 Callback<NoRef*(void)> normal_non_refcounted_cb = |
337 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_); | 337 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_); |
338 normal_cb.Run(); | 338 normal_cb.Run(); |
339 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run()); | 339 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run()); |
340 | 340 |
341 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); | 341 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 // - Passed() can be constructed from a scoper rvalue. | 708 // - Passed() can be constructed from a scoper rvalue. |
709 // - Using Passed() gives Callback Ownership. | 709 // - Using Passed() gives Callback Ownership. |
710 // - Ownership is transferred from Callback to callee on the first Run(). | 710 // - Ownership is transferred from Callback to callee on the first Run(). |
711 // - Callback supports unbound arguments. | 711 // - Callback supports unbound arguments. |
712 TEST_F(BindTest, ScopedPtr) { | 712 TEST_F(BindTest, ScopedPtr) { |
713 int deletes = 0; | 713 int deletes = 0; |
714 | 714 |
715 // Tests the Passed() function's support for pointers. | 715 // Tests the Passed() function's support for pointers. |
716 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); | 716 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); |
717 Callback<scoped_ptr<DeleteCounter>(void)> unused_callback = | 717 Callback<scoped_ptr<DeleteCounter>(void)> unused_callback = |
718 Bind(&PassThru<scoped_ptr<DeleteCounter> >, Passed(&ptr)); | 718 Bind(&PassThru<scoped_ptr<DeleteCounter>>, Passed(&ptr)); |
719 EXPECT_FALSE(ptr.get()); | 719 EXPECT_FALSE(ptr.get()); |
720 EXPECT_EQ(0, deletes); | 720 EXPECT_EQ(0, deletes); |
721 | 721 |
722 // If we never invoke the Callback, it retains ownership and deletes. | 722 // If we never invoke the Callback, it retains ownership and deletes. |
723 unused_callback.Reset(); | 723 unused_callback.Reset(); |
724 EXPECT_EQ(1, deletes); | 724 EXPECT_EQ(1, deletes); |
725 | 725 |
726 // Tests the Passed() function's support for rvalues. | 726 // Tests the Passed() function's support for rvalues. |
727 deletes = 0; | 727 deletes = 0; |
728 DeleteCounter* counter = new DeleteCounter(&deletes); | 728 DeleteCounter* counter = new DeleteCounter(&deletes); |
(...skipping 16 matching lines...) Expand all Loading... |
745 result.reset(); | 745 result.reset(); |
746 EXPECT_EQ(1, deletes); | 746 EXPECT_EQ(1, deletes); |
747 | 747 |
748 // Test unbound argument forwarding. | 748 // Test unbound argument forwarding. |
749 Callback<scoped_ptr<DeleteCounter>(scoped_ptr<DeleteCounter>)> cb_unbound = | 749 Callback<scoped_ptr<DeleteCounter>(scoped_ptr<DeleteCounter>)> cb_unbound = |
750 Bind(&PassThru<scoped_ptr<DeleteCounter> >); | 750 Bind(&PassThru<scoped_ptr<DeleteCounter> >); |
751 ptr.reset(new DeleteCounter(&deletes)); | 751 ptr.reset(new DeleteCounter(&deletes)); |
752 cb_unbound.Run(ptr.Pass()); | 752 cb_unbound.Run(ptr.Pass()); |
753 } | 753 } |
754 | 754 |
| 755 // RValue support. |
| 756 // - Bind() can take move-only values by RValue-reference. |
| 757 // - Using an RValue gives Callback Ownership. |
| 758 // - Ownership is transferred from Callback to callee on the first Run(). |
| 759 // - Callback supports unbound arguments. |
| 760 TEST_F(BindTest, ScopedPtrRValue) { |
| 761 int deletes = 0; |
| 762 |
| 763 // Tests the Passed() function's support for pointers. |
| 764 scoped_ptr<DeleteCounter> ptr(new DeleteCounter(&deletes)); |
| 765 Callback<scoped_ptr<DeleteCounter>(void)> unused_callback = |
| 766 Bind(&PassThru<scoped_ptr<DeleteCounter>>, std::move(ptr)); |
| 767 EXPECT_FALSE(ptr.get()); |
| 768 EXPECT_EQ(0, deletes); |
| 769 |
| 770 // If we never invoke the Callback, it retains ownership and deletes. |
| 771 unused_callback.Reset(); |
| 772 EXPECT_EQ(1, deletes); |
| 773 |
| 774 // Tests the Passed() function's support for rvalues. |
| 775 deletes = 0; |
| 776 DeleteCounter* counter = new DeleteCounter(&deletes); |
| 777 Callback<scoped_ptr<DeleteCounter>(void)> callback = |
| 778 Bind(&PassThru<scoped_ptr<DeleteCounter> >, |
| 779 scoped_ptr<DeleteCounter>(counter)); |
| 780 EXPECT_FALSE(ptr.get()); |
| 781 EXPECT_EQ(0, deletes); |
| 782 |
| 783 // Check that ownership can be transferred back out. |
| 784 scoped_ptr<DeleteCounter> result = callback.Run(); |
| 785 ASSERT_EQ(counter, result.get()); |
| 786 EXPECT_EQ(0, deletes); |
| 787 |
| 788 // Resetting does not delete since ownership was transferred. |
| 789 callback.Reset(); |
| 790 EXPECT_EQ(0, deletes); |
| 791 |
| 792 // Ensure that we actually did get ownership. |
| 793 result.reset(); |
| 794 EXPECT_EQ(1, deletes); |
| 795 |
| 796 // Test unbound argument forwarding. |
| 797 Callback<scoped_ptr<DeleteCounter>(scoped_ptr<DeleteCounter>)> cb_unbound = |
| 798 Bind(&PassThru<scoped_ptr<DeleteCounter> >); |
| 799 ptr.reset(new DeleteCounter(&deletes)); |
| 800 cb_unbound.Run(std::move(ptr)); |
| 801 } |
| 802 |
| 803 // RValue support. |
| 804 // - Bind() can take move-only values by RValue-reference. |
| 805 // - Using an RValue gives Callback Ownership. |
| 806 // - Ownership is transferred from Callback to callee on the first Run(). |
| 807 // - Callback supports unbound arguments. |
| 808 TEST_F(BindTest, ContainerOfMoveOnlyValues) { |
| 809 int deletes = 0; |
| 810 |
| 811 // Tests the Passed() function's support for pointers. |
| 812 std::vector<scoped_ptr<DeleteCounter>> ptrs; |
| 813 ptrs.emplace_back(new DeleteCounter(&deletes)); |
| 814 Callback<std::vector<scoped_ptr<DeleteCounter>>(void)> unused_callback = |
| 815 Bind(&PassThru<std::vector<scoped_ptr<DeleteCounter>>>, std::move(ptrs)); |
| 816 EXPECT_EQ(0, deletes); |
| 817 |
| 818 // If we never invoke the Callback, it retains ownership and deletes. |
| 819 unused_callback.Reset(); |
| 820 EXPECT_EQ(1, deletes); |
| 821 |
| 822 // Tests the Passed() function's support for rvalues. |
| 823 deletes = 0; |
| 824 ptrs.clear(); |
| 825 DeleteCounter* counter = new DeleteCounter(&deletes); |
| 826 ptrs.emplace_back(counter); |
| 827 Callback<std::vector<scoped_ptr<DeleteCounter>>(void)> callback = |
| 828 Bind(&PassThru<std::vector<scoped_ptr<DeleteCounter>>>, std::move(ptrs)); |
| 829 EXPECT_EQ(0, deletes); |
| 830 |
| 831 // Check that ownership can be transferred back out. |
| 832 std::vector<scoped_ptr<DeleteCounter>> result = callback.Run(); |
| 833 ASSERT_EQ(1u, result.size()); |
| 834 ASSERT_EQ(counter, result[0].get()); |
| 835 EXPECT_EQ(0, deletes); |
| 836 |
| 837 // Resetting does not delete since ownership was transferred. |
| 838 callback.Reset(); |
| 839 EXPECT_EQ(0, deletes); |
| 840 |
| 841 // Ensure that we actually did get ownership. |
| 842 result.clear(); |
| 843 EXPECT_EQ(1, deletes); |
| 844 |
| 845 // Test unbound argument forwarding. |
| 846 Callback<std::vector<scoped_ptr<DeleteCounter>>( |
| 847 std::vector<scoped_ptr<DeleteCounter>>)> |
| 848 cb_unbound = Bind(&PassThru<std::vector<scoped_ptr<DeleteCounter>>>); |
| 849 ptrs.clear(); |
| 850 ptrs.emplace_back(new DeleteCounter(&deletes)); |
| 851 cb_unbound.Run(std::move(ptrs)); |
| 852 } |
| 853 |
755 // Argument Copy-constructor usage for non-reference parameters. | 854 // Argument Copy-constructor usage for non-reference parameters. |
756 // - Bound arguments are only copied once. | 855 // - Bound arguments are only copied once. |
757 // - Forwarded arguments are only copied once. | 856 // - Forwarded arguments are only copied once. |
758 // - Forwarded arguments with coercions are only copied twice (once for the | 857 // - Forwarded arguments with coercions are only copied twice (once for the |
759 // coercion, and one for the final dispatch). | 858 // coercion, and one for the final dispatch). |
760 TEST_F(BindTest, ArgumentCopies) { | 859 TEST_F(BindTest, ArgumentCopies) { |
761 int copies = 0; | 860 int copies = 0; |
762 int assigns = 0; | 861 int assigns = 0; |
763 | 862 |
764 CopyCounter counter(&copies, &assigns); | 863 CopyCounter counter(&copies, &assigns); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 base::Callback<void(int)> null_cb; | 919 base::Callback<void(int)> null_cb; |
821 ASSERT_TRUE(null_cb.is_null()); | 920 ASSERT_TRUE(null_cb.is_null()); |
822 EXPECT_DEATH(base::Bind(null_cb, 42), ""); | 921 EXPECT_DEATH(base::Bind(null_cb, 42), ""); |
823 } | 922 } |
824 | 923 |
825 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && | 924 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && |
826 // GTEST_HAS_DEATH_TEST | 925 // GTEST_HAS_DEATH_TEST |
827 | 926 |
828 } // namespace | 927 } // namespace |
829 } // namespace base | 928 } // namespace base |
OLD | NEW |