Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: base/bind_unittest.cc

Issue 1498973002: WIP: base::Bind for rvalue references. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/bind_internal_win.h ('k') | base/callback.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « base/bind_internal_win.h ('k') | base/callback.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698