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
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6
7 #include <memory>
8 #include <utility>
9 #include <vector>
10
11 #include "base/callback.h"
12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/weak_ptr.h"
16 #include "build/build_config.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using ::testing::Mock;
21 using ::testing::Return;
22 using ::testing::StrictMock;
23
24 namespace base {
25 namespace {
26
27 class IncompleteType;
28
29 class NoRef {
30 public:
NoRef()31 NoRef() {}
32
33 MOCK_METHOD0(VoidMethod0, void());
34 MOCK_CONST_METHOD0(VoidConstMethod0, void());
35
36 MOCK_METHOD0(IntMethod0, int());
37 MOCK_CONST_METHOD0(IntConstMethod0, int());
38
39 private:
40 // Particularly important in this test to ensure no copies are made.
41 DISALLOW_COPY_AND_ASSIGN(NoRef);
42 };
43
44 class HasRef : public NoRef {
45 public:
HasRef()46 HasRef() {}
47
48 MOCK_CONST_METHOD0(AddRef, void());
49 MOCK_CONST_METHOD0(Release, bool());
50
51 private:
52 // Particularly important in this test to ensure no copies are made.
53 DISALLOW_COPY_AND_ASSIGN(HasRef);
54 };
55
56 class HasRefPrivateDtor : public HasRef {
57 private:
~HasRefPrivateDtor()58 ~HasRefPrivateDtor() {}
59 };
60
61 static const int kParentValue = 1;
62 static const int kChildValue = 2;
63
64 class Parent {
65 public:
~Parent()66 virtual ~Parent() {}
AddRef() const67 void AddRef() const {}
Release() const68 void Release() const {}
VirtualSet()69 virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()70 void NonVirtualSet() { value = kParentValue; }
71 int value;
72 };
73
74 class Child : public Parent {
75 public:
~Child()76 ~Child() override {}
VirtualSet()77 void VirtualSet() override { value = kChildValue; }
NonVirtualSet()78 void NonVirtualSet() { value = kChildValue; }
79 };
80
81 class NoRefParent {
82 public:
~NoRefParent()83 virtual ~NoRefParent() {}
VirtualSet()84 virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()85 void NonVirtualSet() { value = kParentValue; }
86 int value;
87 };
88
89 class NoRefChild : public NoRefParent {
90 public:
~NoRefChild()91 ~NoRefChild() override {}
92 private:
VirtualSet()93 void VirtualSet() override { value = kChildValue; }
NonVirtualSet()94 void NonVirtualSet() { value = kChildValue; }
95 };
96
97 // Used for probing the number of copies and moves that occur if a type must be
98 // coerced during argument forwarding in the Run() methods.
99 struct DerivedCopyMoveCounter {
DerivedCopyMoveCounterbase::__anon8607446f0111::DerivedCopyMoveCounter100 DerivedCopyMoveCounter(int* copies,
101 int* assigns,
102 int* move_constructs,
103 int* move_assigns)
104 : copies_(copies),
105 assigns_(assigns),
106 move_constructs_(move_constructs),
107 move_assigns_(move_assigns) {}
108 int* copies_;
109 int* assigns_;
110 int* move_constructs_;
111 int* move_assigns_;
112 };
113
114 // Used for probing the number of copies and moves in an argument.
115 class CopyMoveCounter {
116 public:
CopyMoveCounter(int * copies,int * assigns,int * move_constructs,int * move_assigns)117 CopyMoveCounter(int* copies,
118 int* assigns,
119 int* move_constructs,
120 int* move_assigns)
121 : copies_(copies),
122 assigns_(assigns),
123 move_constructs_(move_constructs),
124 move_assigns_(move_assigns) {}
125
CopyMoveCounter(const CopyMoveCounter & other)126 CopyMoveCounter(const CopyMoveCounter& other)
127 : copies_(other.copies_),
128 assigns_(other.assigns_),
129 move_constructs_(other.move_constructs_),
130 move_assigns_(other.move_assigns_) {
131 (*copies_)++;
132 }
133
CopyMoveCounter(CopyMoveCounter && other)134 CopyMoveCounter(CopyMoveCounter&& other)
135 : copies_(other.copies_),
136 assigns_(other.assigns_),
137 move_constructs_(other.move_constructs_),
138 move_assigns_(other.move_assigns_) {
139 (*move_constructs_)++;
140 }
141
142 // Probing for copies from coercion.
CopyMoveCounter(const DerivedCopyMoveCounter & other)143 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
144 : copies_(other.copies_),
145 assigns_(other.assigns_),
146 move_constructs_(other.move_constructs_),
147 move_assigns_(other.move_assigns_) {
148 (*copies_)++;
149 }
150
151 // Probing for moves from coercion.
CopyMoveCounter(DerivedCopyMoveCounter && other)152 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
153 : copies_(other.copies_),
154 assigns_(other.assigns_),
155 move_constructs_(other.move_constructs_),
156 move_assigns_(other.move_assigns_) {
157 (*move_constructs_)++;
158 }
159
operator =(const CopyMoveCounter & rhs)160 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
161 copies_ = rhs.copies_;
162 assigns_ = rhs.assigns_;
163 move_constructs_ = rhs.move_constructs_;
164 move_assigns_ = rhs.move_assigns_;
165
166 (*assigns_)++;
167
168 return *this;
169 }
170
operator =(CopyMoveCounter && rhs)171 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
172 copies_ = rhs.copies_;
173 assigns_ = rhs.assigns_;
174 move_constructs_ = rhs.move_constructs_;
175 move_assigns_ = rhs.move_assigns_;
176
177 (*move_assigns_)++;
178
179 return *this;
180 }
181
copies() const182 int copies() const {
183 return *copies_;
184 }
185
186 private:
187 int* copies_;
188 int* assigns_;
189 int* move_constructs_;
190 int* move_assigns_;
191 };
192
193 // Used for probing the number of copies in an argument. The instance is a
194 // copyable and non-movable type.
195 class CopyCounter {
196 public:
CopyCounter(int * copies,int * assigns)197 CopyCounter(int* copies, int* assigns)
198 : counter_(copies, assigns, nullptr, nullptr) {}
CopyCounter(const CopyCounter & other)199 CopyCounter(const CopyCounter& other) : counter_(other.counter_) {}
operator =(const CopyCounter & other)200 CopyCounter& operator=(const CopyCounter& other) {
201 counter_ = other.counter_;
202 return *this;
203 }
204
CopyCounter(const DerivedCopyMoveCounter & other)205 explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {}
206
copies() const207 int copies() const { return counter_.copies(); }
208
209 private:
210 CopyMoveCounter counter_;
211 };
212
213 // Used for probing the number of moves in an argument. The instance is a
214 // non-copyable and movable type.
215 class MoveCounter {
216 public:
MoveCounter(int * move_constructs,int * move_assigns)217 MoveCounter(int* move_constructs, int* move_assigns)
218 : counter_(nullptr, nullptr, move_constructs, move_assigns) {}
MoveCounter(MoveCounter && other)219 MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {}
operator =(MoveCounter && other)220 MoveCounter& operator=(MoveCounter&& other) {
221 counter_ = std::move(other.counter_);
222 return *this;
223 }
224
MoveCounter(DerivedCopyMoveCounter && other)225 explicit MoveCounter(DerivedCopyMoveCounter&& other)
226 : counter_(std::move(other)) {}
227
228 private:
229 CopyMoveCounter counter_;
230 };
231
232 class DeleteCounter {
233 public:
DeleteCounter(int * deletes)234 explicit DeleteCounter(int* deletes)
235 : deletes_(deletes) {
236 }
237
~DeleteCounter()238 ~DeleteCounter() {
239 (*deletes_)++;
240 }
241
VoidMethod0()242 void VoidMethod0() {}
243
244 private:
245 int* deletes_;
246 };
247
248 template <typename T>
PassThru(T scoper)249 T PassThru(T scoper) {
250 return scoper;
251 }
252
253 // Some test functions that we can Bind to.
254 template <typename T>
PolymorphicIdentity(T t)255 T PolymorphicIdentity(T t) {
256 return t;
257 }
258
259 template <typename... Ts>
260 struct VoidPolymorphic {
Runbase::__anon8607446f0111::VoidPolymorphic261 static void Run(Ts... t) {}
262 };
263
Identity(int n)264 int Identity(int n) {
265 return n;
266 }
267
ArrayGet(const int array[],int n)268 int ArrayGet(const int array[], int n) {
269 return array[n];
270 }
271
Sum(int a,int b,int c,int d,int e,int f)272 int Sum(int a, int b, int c, int d, int e, int f) {
273 return a + b + c + d + e + f;
274 }
275
CStringIdentity(const char * s)276 const char* CStringIdentity(const char* s) {
277 return s;
278 }
279
GetCopies(const CopyMoveCounter & counter)280 int GetCopies(const CopyMoveCounter& counter) {
281 return counter.copies();
282 }
283
UnwrapNoRefParent(NoRefParent p)284 int UnwrapNoRefParent(NoRefParent p) {
285 return p.value;
286 }
287
UnwrapNoRefParentPtr(NoRefParent * p)288 int UnwrapNoRefParentPtr(NoRefParent* p) {
289 return p->value;
290 }
291
UnwrapNoRefParentConstRef(const NoRefParent & p)292 int UnwrapNoRefParentConstRef(const NoRefParent& p) {
293 return p.value;
294 }
295
RefArgSet(int & n)296 void RefArgSet(int &n) {
297 n = 2;
298 }
299
PtrArgSet(int * n)300 void PtrArgSet(int *n) {
301 *n = 2;
302 }
303
FunctionWithWeakFirstParam(WeakPtr<NoRef> o,int n)304 int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
305 return n;
306 }
307
FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef> & o,int n)308 int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
309 return n;
310 }
311
TakesACallback(const Closure & callback)312 void TakesACallback(const Closure& callback) {
313 callback.Run();
314 }
315
316 class BindTest : public ::testing::Test {
317 public:
BindTest()318 BindTest() {
319 const_has_ref_ptr_ = &has_ref_;
320 const_no_ref_ptr_ = &no_ref_;
321 static_func_mock_ptr = &static_func_mock_;
322 }
323
~BindTest()324 virtual ~BindTest() {
325 }
326
VoidFunc0()327 static void VoidFunc0() {
328 static_func_mock_ptr->VoidMethod0();
329 }
330
IntFunc0()331 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
332
333 protected:
334 StrictMock<NoRef> no_ref_;
335 StrictMock<HasRef> has_ref_;
336 const HasRef* const_has_ref_ptr_;
337 const NoRef* const_no_ref_ptr_;
338 StrictMock<NoRef> static_func_mock_;
339
340 // Used by the static functions to perform expectations.
341 static StrictMock<NoRef>* static_func_mock_ptr;
342
343 private:
344 DISALLOW_COPY_AND_ASSIGN(BindTest);
345 };
346
347 StrictMock<NoRef>* BindTest::static_func_mock_ptr;
348
349 // Sanity check that we can instantiate a callback for each arity.
TEST_F(BindTest,ArityTest)350 TEST_F(BindTest, ArityTest) {
351 Callback<int()> c0 = Bind(&Sum, 32, 16, 8, 4, 2, 1);
352 EXPECT_EQ(63, c0.Run());
353
354 Callback<int(int)> c1 = Bind(&Sum, 32, 16, 8, 4, 2);
355 EXPECT_EQ(75, c1.Run(13));
356
357 Callback<int(int,int)> c2 = Bind(&Sum, 32, 16, 8, 4);
358 EXPECT_EQ(85, c2.Run(13, 12));
359
360 Callback<int(int,int,int)> c3 = Bind(&Sum, 32, 16, 8);
361 EXPECT_EQ(92, c3.Run(13, 12, 11));
362
363 Callback<int(int,int,int,int)> c4 = Bind(&Sum, 32, 16);
364 EXPECT_EQ(94, c4.Run(13, 12, 11, 10));
365
366 Callback<int(int,int,int,int,int)> c5 = Bind(&Sum, 32);
367 EXPECT_EQ(87, c5.Run(13, 12, 11, 10, 9));
368
369 Callback<int(int,int,int,int,int,int)> c6 = Bind(&Sum);
370 EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14));
371 }
372
373 // Test the Currying ability of the Callback system.
TEST_F(BindTest,CurryingTest)374 TEST_F(BindTest, CurryingTest) {
375 Callback<int(int,int,int,int,int,int)> c6 = Bind(&Sum);
376 EXPECT_EQ(69, c6.Run(13, 12, 11, 10, 9, 14));
377
378 Callback<int(int,int,int,int,int)> c5 = Bind(c6, 32);
379 EXPECT_EQ(87, c5.Run(13, 12, 11, 10, 9));
380
381 Callback<int(int,int,int,int)> c4 = Bind(c5, 16);
382 EXPECT_EQ(94, c4.Run(13, 12, 11, 10));
383
384 Callback<int(int,int,int)> c3 = Bind(c4, 8);
385 EXPECT_EQ(92, c3.Run(13, 12, 11));
386
387 Callback<int(int,int)> c2 = Bind(c3, 4);
388 EXPECT_EQ(85, c2.Run(13, 12));
389
390 Callback<int(int)> c1 = Bind(c2, 2);
391 EXPECT_EQ(75, c1.Run(13));
392
393 Callback<int()> c0 = Bind(c1, 1);
394 EXPECT_EQ(63, c0.Run());
395 }
396
397 // Test that currying the rvalue result of another Bind() works correctly.
398 // - rvalue should be usable as argument to Bind().
399 // - multiple runs of resulting Callback remain valid.
TEST_F(BindTest,CurryingRvalueResultOfBind)400 TEST_F(BindTest, CurryingRvalueResultOfBind) {
401 int n = 0;
402 Closure cb = base::Bind(&TakesACallback, base::Bind(&PtrArgSet, &n));
403
404 // If we implement Bind() such that the return value has auto_ptr-like
405 // semantics, the second call here will fail because ownership of
406 // the internal BindState<> would have been transfered to a *temporary*
407 // constructon of a Callback object on the first call.
408 cb.Run();
409 EXPECT_EQ(2, n);
410
411 n = 0;
412 cb.Run();
413 EXPECT_EQ(2, n);
414 }
415
416 // Function type support.
417 // - Normal function.
418 // - Normal function bound with non-refcounted first argument.
419 // - Method bound to non-const object.
420 // - Method bound to scoped_refptr.
421 // - Const method bound to non-const object.
422 // - Const method bound to const object.
423 // - Derived classes can be used with pointers to non-virtual base functions.
424 // - Derived classes can be used with pointers to virtual base functions (and
425 // preserve virtual dispatch).
TEST_F(BindTest,FunctionTypeSupport)426 TEST_F(BindTest, FunctionTypeSupport) {
427 EXPECT_CALL(static_func_mock_, VoidMethod0());
428 EXPECT_CALL(has_ref_, AddRef()).Times(4);
429 EXPECT_CALL(has_ref_, Release()).Times(4);
430 EXPECT_CALL(has_ref_, VoidMethod0()).Times(2);
431 EXPECT_CALL(has_ref_, VoidConstMethod0()).Times(2);
432
433 Closure normal_cb = Bind(&VoidFunc0);
434 Callback<NoRef*()> normal_non_refcounted_cb =
435 Bind(&PolymorphicIdentity<NoRef*>, &no_ref_);
436 normal_cb.Run();
437 EXPECT_EQ(&no_ref_, normal_non_refcounted_cb.Run());
438
439 Closure method_cb = Bind(&HasRef::VoidMethod0, &has_ref_);
440 Closure method_refptr_cb = Bind(&HasRef::VoidMethod0,
441 make_scoped_refptr(&has_ref_));
442 Closure const_method_nonconst_obj_cb = Bind(&HasRef::VoidConstMethod0,
443 &has_ref_);
444 Closure const_method_const_obj_cb = Bind(&HasRef::VoidConstMethod0,
445 const_has_ref_ptr_);
446 method_cb.Run();
447 method_refptr_cb.Run();
448 const_method_nonconst_obj_cb.Run();
449 const_method_const_obj_cb.Run();
450
451 Child child;
452 child.value = 0;
453 Closure virtual_set_cb = Bind(&Parent::VirtualSet, &child);
454 virtual_set_cb.Run();
455 EXPECT_EQ(kChildValue, child.value);
456
457 child.value = 0;
458 Closure non_virtual_set_cb = Bind(&Parent::NonVirtualSet, &child);
459 non_virtual_set_cb.Run();
460 EXPECT_EQ(kParentValue, child.value);
461 }
462
463 // Return value support.
464 // - Function with return value.
465 // - Method with return value.
466 // - Const method with return value.
TEST_F(BindTest,ReturnValues)467 TEST_F(BindTest, ReturnValues) {
468 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
469 EXPECT_CALL(has_ref_, AddRef()).Times(3);
470 EXPECT_CALL(has_ref_, Release()).Times(3);
471 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(31337));
472 EXPECT_CALL(has_ref_, IntConstMethod0())
473 .WillOnce(Return(41337))
474 .WillOnce(Return(51337));
475
476 Callback<int()> normal_cb = Bind(&IntFunc0);
477 Callback<int()> method_cb = Bind(&HasRef::IntMethod0, &has_ref_);
478 Callback<int()> const_method_nonconst_obj_cb =
479 Bind(&HasRef::IntConstMethod0, &has_ref_);
480 Callback<int()> const_method_const_obj_cb =
481 Bind(&HasRef::IntConstMethod0, const_has_ref_ptr_);
482 EXPECT_EQ(1337, normal_cb.Run());
483 EXPECT_EQ(31337, method_cb.Run());
484 EXPECT_EQ(41337, const_method_nonconst_obj_cb.Run());
485 EXPECT_EQ(51337, const_method_const_obj_cb.Run());
486 }
487
488 // IgnoreResult adapter test.
489 // - Function with return value.
490 // - Method with return value.
491 // - Const Method with return.
492 // - Method with return value bound to WeakPtr<>.
493 // - Const Method with return bound to WeakPtr<>.
TEST_F(BindTest,IgnoreResult)494 TEST_F(BindTest, IgnoreResult) {
495 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
496 EXPECT_CALL(has_ref_, AddRef()).Times(2);
497 EXPECT_CALL(has_ref_, Release()).Times(2);
498 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
499 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
500 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
501 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
502
503 Closure normal_func_cb = Bind(IgnoreResult(&IntFunc0));
504 normal_func_cb.Run();
505
506 Closure non_void_method_cb =
507 Bind(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
508 non_void_method_cb.Run();
509
510 Closure non_void_const_method_cb =
511 Bind(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
512 non_void_const_method_cb.Run();
513
514 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
515 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
516
517 Closure non_void_weak_method_cb =
518 Bind(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
519 non_void_weak_method_cb.Run();
520
521 Closure non_void_weak_const_method_cb =
522 Bind(IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
523 non_void_weak_const_method_cb.Run();
524
525 weak_factory.InvalidateWeakPtrs();
526 non_void_weak_const_method_cb.Run();
527 non_void_weak_method_cb.Run();
528 }
529
530 // Argument binding tests.
531 // - Argument binding to primitive.
532 // - Argument binding to primitive pointer.
533 // - Argument binding to a literal integer.
534 // - Argument binding to a literal string.
535 // - Argument binding with template function.
536 // - Argument binding to an object.
537 // - Argument binding to pointer to incomplete type.
538 // - Argument gets type converted.
539 // - Pointer argument gets converted.
540 // - Const Reference forces conversion.
TEST_F(BindTest,ArgumentBinding)541 TEST_F(BindTest, ArgumentBinding) {
542 int n = 2;
543
544 Callback<int()> bind_primitive_cb = Bind(&Identity, n);
545 EXPECT_EQ(n, bind_primitive_cb.Run());
546
547 Callback<int*()> bind_primitive_pointer_cb =
548 Bind(&PolymorphicIdentity<int*>, &n);
549 EXPECT_EQ(&n, bind_primitive_pointer_cb.Run());
550
551 Callback<int()> bind_int_literal_cb = Bind(&Identity, 3);
552 EXPECT_EQ(3, bind_int_literal_cb.Run());
553
554 Callback<const char*()> bind_string_literal_cb =
555 Bind(&CStringIdentity, "hi");
556 EXPECT_STREQ("hi", bind_string_literal_cb.Run());
557
558 Callback<int()> bind_template_function_cb =
559 Bind(&PolymorphicIdentity<int>, 4);
560 EXPECT_EQ(4, bind_template_function_cb.Run());
561
562 NoRefParent p;
563 p.value = 5;
564 Callback<int()> bind_object_cb = Bind(&UnwrapNoRefParent, p);
565 EXPECT_EQ(5, bind_object_cb.Run());
566
567 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
568 Callback<IncompleteType*()> bind_incomplete_ptr_cb =
569 Bind(&PolymorphicIdentity<IncompleteType*>, incomplete_ptr);
570 EXPECT_EQ(incomplete_ptr, bind_incomplete_ptr_cb.Run());
571
572 NoRefChild c;
573 c.value = 6;
574 Callback<int()> bind_promotes_cb = Bind(&UnwrapNoRefParent, c);
575 EXPECT_EQ(6, bind_promotes_cb.Run());
576
577 c.value = 7;
578 Callback<int()> bind_pointer_promotes_cb =
579 Bind(&UnwrapNoRefParentPtr, &c);
580 EXPECT_EQ(7, bind_pointer_promotes_cb.Run());
581
582 c.value = 8;
583 Callback<int()> bind_const_reference_promotes_cb =
584 Bind(&UnwrapNoRefParentConstRef, c);
585 EXPECT_EQ(8, bind_const_reference_promotes_cb.Run());
586 }
587
588 // Unbound argument type support tests.
589 // - Unbound value.
590 // - Unbound pointer.
591 // - Unbound reference.
592 // - Unbound const reference.
593 // - Unbound unsized array.
594 // - Unbound sized array.
595 // - Unbound array-of-arrays.
TEST_F(BindTest,UnboundArgumentTypeSupport)596 TEST_F(BindTest, UnboundArgumentTypeSupport) {
597 Callback<void(int)> unbound_value_cb = Bind(&VoidPolymorphic<int>::Run);
598 Callback<void(int*)> unbound_pointer_cb = Bind(&VoidPolymorphic<int*>::Run);
599 Callback<void(int&)> unbound_ref_cb = Bind(&VoidPolymorphic<int&>::Run);
600 Callback<void(const int&)> unbound_const_ref_cb =
601 Bind(&VoidPolymorphic<const int&>::Run);
602 Callback<void(int[])> unbound_unsized_array_cb =
603 Bind(&VoidPolymorphic<int[]>::Run);
604 Callback<void(int[2])> unbound_sized_array_cb =
605 Bind(&VoidPolymorphic<int[2]>::Run);
606 Callback<void(int[][2])> unbound_array_of_arrays_cb =
607 Bind(&VoidPolymorphic<int[][2]>::Run);
608
609 Callback<void(int&)> unbound_ref_with_bound_arg =
610 Bind(&VoidPolymorphic<int, int&>::Run, 1);
611 }
612
613 // Function with unbound reference parameter.
614 // - Original parameter is modified by callback.
TEST_F(BindTest,UnboundReferenceSupport)615 TEST_F(BindTest, UnboundReferenceSupport) {
616 int n = 0;
617 Callback<void(int&)> unbound_ref_cb = Bind(&RefArgSet);
618 unbound_ref_cb.Run(n);
619 EXPECT_EQ(2, n);
620 }
621
622 // Functions that take reference parameters.
623 // - Forced reference parameter type still stores a copy.
624 // - Forced const reference parameter type still stores a copy.
TEST_F(BindTest,ReferenceArgumentBinding)625 TEST_F(BindTest, ReferenceArgumentBinding) {
626 int n = 1;
627 int& ref_n = n;
628 const int& const_ref_n = n;
629
630 Callback<int()> ref_copies_cb = Bind(&Identity, ref_n);
631 EXPECT_EQ(n, ref_copies_cb.Run());
632 n++;
633 EXPECT_EQ(n - 1, ref_copies_cb.Run());
634
635 Callback<int()> const_ref_copies_cb = Bind(&Identity, const_ref_n);
636 EXPECT_EQ(n, const_ref_copies_cb.Run());
637 n++;
638 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
639 }
640
641 // Check that we can pass in arrays and have them be stored as a pointer.
642 // - Array of values stores a pointer.
643 // - Array of const values stores a pointer.
TEST_F(BindTest,ArrayArgumentBinding)644 TEST_F(BindTest, ArrayArgumentBinding) {
645 int array[4] = {1, 1, 1, 1};
646 const int (*const_array_ptr)[4] = &array;
647
648 Callback<int()> array_cb = Bind(&ArrayGet, array, 1);
649 EXPECT_EQ(1, array_cb.Run());
650
651 Callback<int()> const_array_cb = Bind(&ArrayGet, *const_array_ptr, 1);
652 EXPECT_EQ(1, const_array_cb.Run());
653
654 array[1] = 3;
655 EXPECT_EQ(3, array_cb.Run());
656 EXPECT_EQ(3, const_array_cb.Run());
657 }
658
659 // Unretained() wrapper support.
660 // - Method bound to Unretained() non-const object.
661 // - Const method bound to Unretained() non-const object.
662 // - Const method bound to Unretained() const object.
TEST_F(BindTest,Unretained)663 TEST_F(BindTest, Unretained) {
664 EXPECT_CALL(no_ref_, VoidMethod0());
665 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
666
667 Callback<void()> method_cb =
668 Bind(&NoRef::VoidMethod0, Unretained(&no_ref_));
669 method_cb.Run();
670
671 Callback<void()> const_method_cb =
672 Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref_));
673 const_method_cb.Run();
674
675 Callback<void()> const_method_const_ptr_cb =
676 Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr_));
677 const_method_const_ptr_cb.Run();
678 }
679
680 // WeakPtr() support.
681 // - Method bound to WeakPtr<> to non-const object.
682 // - Const method bound to WeakPtr<> to non-const object.
683 // - Const method bound to WeakPtr<> to const object.
684 // - Normal Function with WeakPtr<> as P1 can have return type and is
685 // not canceled.
TEST_F(BindTest,WeakPtr)686 TEST_F(BindTest, WeakPtr) {
687 EXPECT_CALL(no_ref_, VoidMethod0());
688 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
689
690 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
691 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
692
693 Closure method_cb =
694 Bind(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
695 method_cb.Run();
696
697 Closure const_method_cb =
698 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
699 const_method_cb.Run();
700
701 Closure const_method_const_ptr_cb =
702 Bind(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
703 const_method_const_ptr_cb.Run();
704
705 Callback<int(int)> normal_func_cb =
706 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
707 EXPECT_EQ(1, normal_func_cb.Run(1));
708
709 weak_factory.InvalidateWeakPtrs();
710 const_weak_factory.InvalidateWeakPtrs();
711
712 method_cb.Run();
713 const_method_cb.Run();
714 const_method_const_ptr_cb.Run();
715
716 // Still runs even after the pointers are invalidated.
717 EXPECT_EQ(2, normal_func_cb.Run(2));
718 }
719
720 // ConstRef() wrapper support.
721 // - Binding w/o ConstRef takes a copy.
722 // - Binding a ConstRef takes a reference.
723 // - Binding ConstRef to a function ConstRef does not copy on invoke.
TEST_F(BindTest,ConstRef)724 TEST_F(BindTest, ConstRef) {
725 int n = 1;
726
727 Callback<int()> copy_cb = Bind(&Identity, n);
728 Callback<int()> const_ref_cb = Bind(&Identity, ConstRef(n));
729 EXPECT_EQ(n, copy_cb.Run());
730 EXPECT_EQ(n, const_ref_cb.Run());
731 n++;
732 EXPECT_EQ(n - 1, copy_cb.Run());
733 EXPECT_EQ(n, const_ref_cb.Run());
734
735 int copies = 0;
736 int assigns = 0;
737 int move_constructs = 0;
738 int move_assigns = 0;
739 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
740 Callback<int()> all_const_ref_cb =
741 Bind(&GetCopies, ConstRef(counter));
742 EXPECT_EQ(0, all_const_ref_cb.Run());
743 EXPECT_EQ(0, copies);
744 EXPECT_EQ(0, assigns);
745 EXPECT_EQ(0, move_constructs);
746 EXPECT_EQ(0, move_assigns);
747 }
748
TEST_F(BindTest,ScopedRefptr)749 TEST_F(BindTest, ScopedRefptr) {
750 EXPECT_CALL(has_ref_, AddRef()).Times(1);
751 EXPECT_CALL(has_ref_, Release()).Times(1);
752
753 const scoped_refptr<HasRef> refptr(&has_ref_);
754 Callback<int()> scoped_refptr_const_ref_cb =
755 Bind(&FunctionWithScopedRefptrFirstParam, base::ConstRef(refptr), 1);
756 EXPECT_EQ(1, scoped_refptr_const_ref_cb.Run());
757 }
758
759 // Test Owned() support.
TEST_F(BindTest,Owned)760 TEST_F(BindTest, Owned) {
761 int deletes = 0;
762 DeleteCounter* counter = new DeleteCounter(&deletes);
763
764 // If we don't capture, delete happens on Callback destruction/reset.
765 // return the same value.
766 Callback<DeleteCounter*()> no_capture_cb =
767 Bind(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
768 ASSERT_EQ(counter, no_capture_cb.Run());
769 ASSERT_EQ(counter, no_capture_cb.Run());
770 EXPECT_EQ(0, deletes);
771 no_capture_cb.Reset(); // This should trigger a delete.
772 EXPECT_EQ(1, deletes);
773
774 deletes = 0;
775 counter = new DeleteCounter(&deletes);
776 base::Closure own_object_cb =
777 Bind(&DeleteCounter::VoidMethod0, Owned(counter));
778 own_object_cb.Run();
779 EXPECT_EQ(0, deletes);
780 own_object_cb.Reset();
781 EXPECT_EQ(1, deletes);
782 }
783
TEST_F(BindTest,UniquePtrReceiver)784 TEST_F(BindTest, UniquePtrReceiver) {
785 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
786 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
787 Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
788 }
789
790 // Tests for Passed() wrapper support:
791 // - Passed() can be constructed from a pointer to scoper.
792 // - Passed() can be constructed from a scoper rvalue.
793 // - Using Passed() gives Callback Ownership.
794 // - Ownership is transferred from Callback to callee on the first Run().
795 // - Callback supports unbound arguments.
796 template <typename T>
797 class BindMoveOnlyTypeTest : public ::testing::Test {
798 };
799
800 struct CustomDeleter {
operator ()base::__anon8607446f0111::CustomDeleter801 void operator()(DeleteCounter* c) { delete c; }
802 };
803
804 using MoveOnlyTypesToTest =
805 ::testing::Types<std::unique_ptr<DeleteCounter>,
806 std::unique_ptr<DeleteCounter>,
807 std::unique_ptr<DeleteCounter, CustomDeleter>>;
808 TYPED_TEST_CASE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
809
TYPED_TEST(BindMoveOnlyTypeTest,PassedToBoundCallback)810 TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
811 int deletes = 0;
812
813 TypeParam ptr(new DeleteCounter(&deletes));
814 Callback<TypeParam()> callback = Bind(&PassThru<TypeParam>, Passed(&ptr));
815 EXPECT_FALSE(ptr.get());
816 EXPECT_EQ(0, deletes);
817
818 // If we never invoke the Callback, it retains ownership and deletes.
819 callback.Reset();
820 EXPECT_EQ(1, deletes);
821 }
822
TYPED_TEST(BindMoveOnlyTypeTest,PassedWithRvalue)823 TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
824 int deletes = 0;
825 Callback<TypeParam()> callback = Bind(
826 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
827 EXPECT_EQ(0, deletes);
828
829 // If we never invoke the Callback, it retains ownership and deletes.
830 callback.Reset();
831 EXPECT_EQ(1, deletes);
832 }
833
834 // Check that ownership can be transferred back out.
TYPED_TEST(BindMoveOnlyTypeTest,ReturnMoveOnlyType)835 TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
836 int deletes = 0;
837 DeleteCounter* counter = new DeleteCounter(&deletes);
838 Callback<TypeParam()> callback =
839 Bind(&PassThru<TypeParam>, Passed(TypeParam(counter)));
840 TypeParam result = callback.Run();
841 ASSERT_EQ(counter, result.get());
842 EXPECT_EQ(0, deletes);
843
844 // Resetting does not delete since ownership was transferred.
845 callback.Reset();
846 EXPECT_EQ(0, deletes);
847
848 // Ensure that we actually did get ownership.
849 result.reset();
850 EXPECT_EQ(1, deletes);
851 }
852
TYPED_TEST(BindMoveOnlyTypeTest,UnboundForwarding)853 TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
854 int deletes = 0;
855 TypeParam ptr(new DeleteCounter(&deletes));
856 // Test unbound argument forwarding.
857 Callback<TypeParam(TypeParam)> cb_unbound = Bind(&PassThru<TypeParam>);
858 cb_unbound.Run(std::move(ptr));
859 EXPECT_EQ(1, deletes);
860 }
861
VerifyVector(const std::vector<std::unique_ptr<int>> & v)862 void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
863 ASSERT_EQ(1u, v.size());
864 EXPECT_EQ(12345, *v[0]);
865 }
866
AcceptAndReturnMoveOnlyVector(std::vector<std::unique_ptr<int>> v)867 std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
868 std::vector<std::unique_ptr<int>> v) {
869 VerifyVector(v);
870 return v;
871 }
872
873 // Test that a vector containing move-only types can be used with Callback.
TEST_F(BindTest,BindMoveOnlyVector)874 TEST_F(BindTest, BindMoveOnlyVector) {
875 using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
876
877 MoveOnlyVector v;
878 v.push_back(WrapUnique(new int(12345)));
879
880 // Early binding should work:
881 base::Callback<MoveOnlyVector()> bound_cb =
882 base::Bind(&AcceptAndReturnMoveOnlyVector, Passed(&v));
883 MoveOnlyVector intermediate_result = bound_cb.Run();
884 VerifyVector(intermediate_result);
885
886 // As should passing it as an argument to Run():
887 base::Callback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
888 base::Bind(&AcceptAndReturnMoveOnlyVector);
889 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
890 VerifyVector(final_result);
891 }
892
893 // Argument copy-constructor usage for non-reference copy-only parameters.
894 // - Bound arguments are only copied once.
895 // - Forwarded arguments are only copied once.
896 // - Forwarded arguments with coercions are only copied twice (once for the
897 // coercion, and one for the final dispatch).
TEST_F(BindTest,ArgumentCopies)898 TEST_F(BindTest, ArgumentCopies) {
899 int copies = 0;
900 int assigns = 0;
901
902 CopyCounter counter(&copies, &assigns);
903 Bind(&VoidPolymorphic<CopyCounter>::Run, counter);
904 EXPECT_EQ(1, copies);
905 EXPECT_EQ(0, assigns);
906
907 copies = 0;
908 assigns = 0;
909 Bind(&VoidPolymorphic<CopyCounter>::Run, CopyCounter(&copies, &assigns));
910 EXPECT_EQ(1, copies);
911 EXPECT_EQ(0, assigns);
912
913 copies = 0;
914 assigns = 0;
915 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
916 EXPECT_EQ(2, copies);
917 EXPECT_EQ(0, assigns);
918
919 copies = 0;
920 assigns = 0;
921 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(&copies, &assigns));
922 EXPECT_EQ(1, copies);
923 EXPECT_EQ(0, assigns);
924
925 copies = 0;
926 assigns = 0;
927 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
928 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
929 EXPECT_EQ(2, copies);
930 EXPECT_EQ(0, assigns);
931
932 copies = 0;
933 assigns = 0;
934 Bind(&VoidPolymorphic<CopyCounter>::Run)
935 .Run(CopyCounter(
936 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
937 EXPECT_EQ(2, copies);
938 EXPECT_EQ(0, assigns);
939 }
940
941 // Argument move-constructor usage for move-only parameters.
942 // - Bound arguments passed by move are not copied.
TEST_F(BindTest,ArgumentMoves)943 TEST_F(BindTest, ArgumentMoves) {
944 int move_constructs = 0;
945 int move_assigns = 0;
946
947 Bind(&VoidPolymorphic<const MoveCounter&>::Run,
948 MoveCounter(&move_constructs, &move_assigns));
949 EXPECT_EQ(1, move_constructs);
950 EXPECT_EQ(0, move_assigns);
951
952 // TODO(tzik): Support binding move-only type into a non-reference parameter
953 // of a variant of Callback.
954
955 move_constructs = 0;
956 move_assigns = 0;
957 Bind(&VoidPolymorphic<MoveCounter>::Run)
958 .Run(MoveCounter(&move_constructs, &move_assigns));
959 EXPECT_EQ(1, move_constructs);
960 EXPECT_EQ(0, move_assigns);
961
962 move_constructs = 0;
963 move_assigns = 0;
964 Bind(&VoidPolymorphic<MoveCounter>::Run)
965 .Run(MoveCounter(DerivedCopyMoveCounter(
966 nullptr, nullptr, &move_constructs, &move_assigns)));
967 EXPECT_EQ(2, move_constructs);
968 EXPECT_EQ(0, move_assigns);
969 }
970
971 // Argument constructor usage for non-reference movable-copyable
972 // parameters.
973 // - Bound arguments passed by move are not copied.
974 // - Forwarded arguments are only copied once.
975 // - Forwarded arguments with coercions are only copied once and moved once.
TEST_F(BindTest,ArgumentCopiesAndMoves)976 TEST_F(BindTest, ArgumentCopiesAndMoves) {
977 int copies = 0;
978 int assigns = 0;
979 int move_constructs = 0;
980 int move_assigns = 0;
981
982 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
983 Bind(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
984 EXPECT_EQ(1, copies);
985 EXPECT_EQ(0, assigns);
986 EXPECT_EQ(0, move_constructs);
987 EXPECT_EQ(0, move_assigns);
988
989 copies = 0;
990 assigns = 0;
991 move_constructs = 0;
992 move_assigns = 0;
993 Bind(&VoidPolymorphic<CopyMoveCounter>::Run,
994 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
995 EXPECT_EQ(0, copies);
996 EXPECT_EQ(0, assigns);
997 EXPECT_EQ(1, move_constructs);
998 EXPECT_EQ(0, move_assigns);
999
1000 copies = 0;
1001 assigns = 0;
1002 move_constructs = 0;
1003 move_assigns = 0;
1004 Bind(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter);
1005 EXPECT_EQ(1, copies);
1006 EXPECT_EQ(0, assigns);
1007 EXPECT_EQ(1, move_constructs);
1008 EXPECT_EQ(0, move_assigns);
1009
1010 copies = 0;
1011 assigns = 0;
1012 move_constructs = 0;
1013 move_assigns = 0;
1014 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1015 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1016 EXPECT_EQ(0, copies);
1017 EXPECT_EQ(0, assigns);
1018 EXPECT_EQ(1, move_constructs);
1019 EXPECT_EQ(0, move_assigns);
1020
1021 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1022 &move_assigns);
1023 copies = 0;
1024 assigns = 0;
1025 move_constructs = 0;
1026 move_assigns = 0;
1027 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1028 .Run(CopyMoveCounter(derived_counter));
1029 EXPECT_EQ(1, copies);
1030 EXPECT_EQ(0, assigns);
1031 EXPECT_EQ(1, move_constructs);
1032 EXPECT_EQ(0, move_assigns);
1033
1034 copies = 0;
1035 assigns = 0;
1036 move_constructs = 0;
1037 move_assigns = 0;
1038 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1039 .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1040 &copies, &assigns, &move_constructs, &move_assigns)));
1041 EXPECT_EQ(0, copies);
1042 EXPECT_EQ(0, assigns);
1043 EXPECT_EQ(2, move_constructs);
1044 EXPECT_EQ(0, move_assigns);
1045 }
1046
TEST_F(BindTest,CapturelessLambda)1047 TEST_F(BindTest, CapturelessLambda) {
1048 EXPECT_FALSE(internal::IsConvertibleToRunType<void>::value);
1049 EXPECT_FALSE(internal::IsConvertibleToRunType<int>::value);
1050 EXPECT_FALSE(internal::IsConvertibleToRunType<void(*)()>::value);
1051 EXPECT_FALSE(internal::IsConvertibleToRunType<void(NoRef::*)()>::value);
1052
1053 auto f = []() {};
1054 EXPECT_TRUE(internal::IsConvertibleToRunType<decltype(f)>::value);
1055
1056 int i = 0;
1057 auto g = [i]() {};
1058 EXPECT_FALSE(internal::IsConvertibleToRunType<decltype(g)>::value);
1059
1060 auto h = [](int, double) { return 'k'; };
1061 EXPECT_TRUE((std::is_same<
1062 char(int, double),
1063 internal::ExtractCallableRunType<decltype(h)>>::value));
1064
1065 EXPECT_EQ(42, Bind([] { return 42; }).Run());
1066 EXPECT_EQ(42, Bind([](int i) { return i * 7; }, 6).Run());
1067
1068 int x = 1;
1069 base::Callback<void(int)> cb =
1070 Bind([](int* x, int i) { *x *= i; }, Unretained(&x));
1071 cb.Run(6);
1072 EXPECT_EQ(6, x);
1073 cb.Run(7);
1074 EXPECT_EQ(42, x);
1075 }
1076
1077 // Callback construction and assignment tests.
1078 // - Construction from an InvokerStorageHolder should not cause ref/deref.
1079 // - Assignment from other callback should only cause one ref
1080 //
1081 // TODO(ajwong): Is there actually a way to test this?
1082
1083 #if defined(OS_WIN)
FastCallFunc(int n)1084 int __fastcall FastCallFunc(int n) {
1085 return n;
1086 }
1087
StdCallFunc(int n)1088 int __stdcall StdCallFunc(int n) {
1089 return n;
1090 }
1091
1092 // Windows specific calling convention support.
1093 // - Can bind a __fastcall function.
1094 // - Can bind a __stdcall function.
TEST_F(BindTest,WindowsCallingConventions)1095 TEST_F(BindTest, WindowsCallingConventions) {
1096 Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1);
1097 EXPECT_EQ(1, fastcall_cb.Run());
1098
1099 Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2);
1100 EXPECT_EQ(2, stdcall_cb.Run());
1101 }
1102 #endif
1103
1104 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
1105
1106 // Test null callbacks cause a DCHECK.
TEST(BindDeathTest,NullCallback)1107 TEST(BindDeathTest, NullCallback) {
1108 base::Callback<void(int)> null_cb;
1109 ASSERT_TRUE(null_cb.is_null());
1110 EXPECT_DEATH(base::Bind(null_cb, 42), "");
1111 }
1112
1113 #endif // (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) &&
1114 // GTEST_HAS_DEATH_TEST
1115
1116 } // namespace
1117 } // namespace base
1118