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 "base/test/gtest_util.h"
17 #include "build/build_config.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 using ::testing::_;
22 using ::testing::Mock;
23 using ::testing::ByMove;
24 using ::testing::Return;
25 using ::testing::StrictMock;
26
27 namespace base {
28 namespace {
29
30 class IncompleteType;
31
32 class NoRef {
33 public:
NoRef()34 NoRef() {}
35
36 MOCK_METHOD0(VoidMethod0, void());
37 MOCK_CONST_METHOD0(VoidConstMethod0, void());
38
39 MOCK_METHOD0(IntMethod0, int());
40 MOCK_CONST_METHOD0(IntConstMethod0, int());
41
42 MOCK_METHOD1(VoidMethodWithIntArg, void(int));
43 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
44
45 private:
46 // Particularly important in this test to ensure no copies are made.
47 DISALLOW_COPY_AND_ASSIGN(NoRef);
48 };
49
50 class HasRef : public NoRef {
51 public:
HasRef()52 HasRef() {}
53
54 MOCK_CONST_METHOD0(AddRef, void());
55 MOCK_CONST_METHOD0(Release, bool());
56
57 private:
58 // Particularly important in this test to ensure no copies are made.
59 DISALLOW_COPY_AND_ASSIGN(HasRef);
60 };
61
62 class HasRefPrivateDtor : public HasRef {
63 private:
~HasRefPrivateDtor()64 ~HasRefPrivateDtor() {}
65 };
66
67 static const int kParentValue = 1;
68 static const int kChildValue = 2;
69
70 class Parent {
71 public:
~Parent()72 virtual ~Parent() {}
AddRef() const73 void AddRef() const {}
Release() const74 void Release() const {}
VirtualSet()75 virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()76 void NonVirtualSet() { value = kParentValue; }
77 int value;
78 };
79
80 class Child : public Parent {
81 public:
~Child()82 ~Child() override {}
VirtualSet()83 void VirtualSet() override { value = kChildValue; }
NonVirtualSet()84 void NonVirtualSet() { value = kChildValue; }
85 };
86
87 class NoRefParent {
88 public:
~NoRefParent()89 virtual ~NoRefParent() {}
VirtualSet()90 virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()91 void NonVirtualSet() { value = kParentValue; }
92 int value;
93 };
94
95 class NoRefChild : public NoRefParent {
96 public:
~NoRefChild()97 ~NoRefChild() override {}
98 private:
VirtualSet()99 void VirtualSet() override { value = kChildValue; }
NonVirtualSet()100 void NonVirtualSet() { value = kChildValue; }
101 };
102
103 // Used for probing the number of copies and moves that occur if a type must be
104 // coerced during argument forwarding in the Run() methods.
105 struct DerivedCopyMoveCounter {
DerivedCopyMoveCounterbase::__anon87abc92c0111::DerivedCopyMoveCounter106 DerivedCopyMoveCounter(int* copies,
107 int* assigns,
108 int* move_constructs,
109 int* move_assigns)
110 : copies_(copies),
111 assigns_(assigns),
112 move_constructs_(move_constructs),
113 move_assigns_(move_assigns) {}
114 int* copies_;
115 int* assigns_;
116 int* move_constructs_;
117 int* move_assigns_;
118 };
119
120 // Used for probing the number of copies and moves in an argument.
121 class CopyMoveCounter {
122 public:
CopyMoveCounter(int * copies,int * assigns,int * move_constructs,int * move_assigns)123 CopyMoveCounter(int* copies,
124 int* assigns,
125 int* move_constructs,
126 int* move_assigns)
127 : copies_(copies),
128 assigns_(assigns),
129 move_constructs_(move_constructs),
130 move_assigns_(move_assigns) {}
131
CopyMoveCounter(const CopyMoveCounter & other)132 CopyMoveCounter(const CopyMoveCounter& other)
133 : copies_(other.copies_),
134 assigns_(other.assigns_),
135 move_constructs_(other.move_constructs_),
136 move_assigns_(other.move_assigns_) {
137 (*copies_)++;
138 }
139
CopyMoveCounter(CopyMoveCounter && other)140 CopyMoveCounter(CopyMoveCounter&& other)
141 : copies_(other.copies_),
142 assigns_(other.assigns_),
143 move_constructs_(other.move_constructs_),
144 move_assigns_(other.move_assigns_) {
145 (*move_constructs_)++;
146 }
147
148 // Probing for copies from coercion.
CopyMoveCounter(const DerivedCopyMoveCounter & other)149 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
150 : copies_(other.copies_),
151 assigns_(other.assigns_),
152 move_constructs_(other.move_constructs_),
153 move_assigns_(other.move_assigns_) {
154 (*copies_)++;
155 }
156
157 // Probing for moves from coercion.
CopyMoveCounter(DerivedCopyMoveCounter && other)158 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
159 : copies_(other.copies_),
160 assigns_(other.assigns_),
161 move_constructs_(other.move_constructs_),
162 move_assigns_(other.move_assigns_) {
163 (*move_constructs_)++;
164 }
165
operator =(const CopyMoveCounter & rhs)166 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
167 copies_ = rhs.copies_;
168 assigns_ = rhs.assigns_;
169 move_constructs_ = rhs.move_constructs_;
170 move_assigns_ = rhs.move_assigns_;
171
172 (*assigns_)++;
173
174 return *this;
175 }
176
operator =(CopyMoveCounter && rhs)177 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
178 copies_ = rhs.copies_;
179 assigns_ = rhs.assigns_;
180 move_constructs_ = rhs.move_constructs_;
181 move_assigns_ = rhs.move_assigns_;
182
183 (*move_assigns_)++;
184
185 return *this;
186 }
187
copies() const188 int copies() const {
189 return *copies_;
190 }
191
192 private:
193 int* copies_;
194 int* assigns_;
195 int* move_constructs_;
196 int* move_assigns_;
197 };
198
199 // Used for probing the number of copies in an argument. The instance is a
200 // copyable and non-movable type.
201 class CopyCounter {
202 public:
CopyCounter(int * copies,int * assigns)203 CopyCounter(int* copies, int* assigns)
204 : counter_(copies, assigns, nullptr, nullptr) {}
CopyCounter(const CopyCounter & other)205 CopyCounter(const CopyCounter& other) : counter_(other.counter_) {}
operator =(const CopyCounter & other)206 CopyCounter& operator=(const CopyCounter& other) {
207 counter_ = other.counter_;
208 return *this;
209 }
210
CopyCounter(const DerivedCopyMoveCounter & other)211 explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {}
212
copies() const213 int copies() const { return counter_.copies(); }
214
215 private:
216 CopyMoveCounter counter_;
217 };
218
219 // Used for probing the number of moves in an argument. The instance is a
220 // non-copyable and movable type.
221 class MoveCounter {
222 public:
MoveCounter(int * move_constructs,int * move_assigns)223 MoveCounter(int* move_constructs, int* move_assigns)
224 : counter_(nullptr, nullptr, move_constructs, move_assigns) {}
MoveCounter(MoveCounter && other)225 MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {}
operator =(MoveCounter && other)226 MoveCounter& operator=(MoveCounter&& other) {
227 counter_ = std::move(other.counter_);
228 return *this;
229 }
230
MoveCounter(DerivedCopyMoveCounter && other)231 explicit MoveCounter(DerivedCopyMoveCounter&& other)
232 : counter_(std::move(other)) {}
233
234 private:
235 CopyMoveCounter counter_;
236 };
237
238 class DeleteCounter {
239 public:
DeleteCounter(int * deletes)240 explicit DeleteCounter(int* deletes)
241 : deletes_(deletes) {
242 }
243
~DeleteCounter()244 ~DeleteCounter() {
245 (*deletes_)++;
246 }
247
VoidMethod0()248 void VoidMethod0() {}
249
250 private:
251 int* deletes_;
252 };
253
254 template <typename T>
PassThru(T scoper)255 T PassThru(T scoper) {
256 return scoper;
257 }
258
259 // Some test functions that we can Bind to.
260 template <typename T>
PolymorphicIdentity(T t)261 T PolymorphicIdentity(T t) {
262 return t;
263 }
264
265 template <typename... Ts>
266 struct VoidPolymorphic {
Runbase::__anon87abc92c0111::VoidPolymorphic267 static void Run(Ts... t) {}
268 };
269
Identity(int n)270 int Identity(int n) {
271 return n;
272 }
273
ArrayGet(const int array[],int n)274 int ArrayGet(const int array[], int n) {
275 return array[n];
276 }
277
Sum(int a,int b,int c,int d,int e,int f)278 int Sum(int a, int b, int c, int d, int e, int f) {
279 return a + b + c + d + e + f;
280 }
281
CStringIdentity(const char * s)282 const char* CStringIdentity(const char* s) {
283 return s;
284 }
285
GetCopies(const CopyMoveCounter & counter)286 int GetCopies(const CopyMoveCounter& counter) {
287 return counter.copies();
288 }
289
UnwrapNoRefParent(NoRefParent p)290 int UnwrapNoRefParent(NoRefParent p) {
291 return p.value;
292 }
293
UnwrapNoRefParentPtr(NoRefParent * p)294 int UnwrapNoRefParentPtr(NoRefParent* p) {
295 return p->value;
296 }
297
UnwrapNoRefParentConstRef(const NoRefParent & p)298 int UnwrapNoRefParentConstRef(const NoRefParent& p) {
299 return p.value;
300 }
301
RefArgSet(int & n)302 void RefArgSet(int &n) {
303 n = 2;
304 }
305
PtrArgSet(int * n)306 void PtrArgSet(int *n) {
307 *n = 2;
308 }
309
FunctionWithWeakFirstParam(WeakPtr<NoRef> o,int n)310 int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
311 return n;
312 }
313
FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef> & o,int n)314 int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
315 return n;
316 }
317
TakesACallback(const Closure & callback)318 void TakesACallback(const Closure& callback) {
319 callback.Run();
320 }
321
322 class BindTest : public ::testing::Test {
323 public:
BindTest()324 BindTest() {
325 const_has_ref_ptr_ = &has_ref_;
326 const_no_ref_ptr_ = &no_ref_;
327 static_func_mock_ptr = &static_func_mock_;
328 }
329
~BindTest()330 virtual ~BindTest() {
331 }
332
VoidFunc0()333 static void VoidFunc0() {
334 static_func_mock_ptr->VoidMethod0();
335 }
336
IntFunc0()337 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
338
339 protected:
340 StrictMock<NoRef> no_ref_;
341 StrictMock<HasRef> has_ref_;
342 const HasRef* const_has_ref_ptr_;
343 const NoRef* const_no_ref_ptr_;
344 StrictMock<NoRef> static_func_mock_;
345
346 // Used by the static functions to perform expectations.
347 static StrictMock<NoRef>* static_func_mock_ptr;
348
349 private:
350 DISALLOW_COPY_AND_ASSIGN(BindTest);
351 };
352
353 StrictMock<NoRef>* BindTest::static_func_mock_ptr;
354 StrictMock<NoRef>* g_func_mock_ptr;
355
VoidFunc0()356 void VoidFunc0() {
357 g_func_mock_ptr->VoidMethod0();
358 }
359
IntFunc0()360 int IntFunc0() {
361 return g_func_mock_ptr->IntMethod0();
362 }
363
TEST_F(BindTest,BasicTest)364 TEST_F(BindTest, BasicTest) {
365 Callback<int(int, int, int)> cb = Bind(&Sum, 32, 16, 8);
366 EXPECT_EQ(92, cb.Run(13, 12, 11));
367
368 Callback<int(int, int, int, int, int, int)> c1 = Bind(&Sum);
369 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
370
371 Callback<int(int, int, int)> c2 = Bind(c1, 32, 16, 8);
372 EXPECT_EQ(86, c2.Run(11, 10, 9));
373
374 Callback<int()> c3 = Bind(c2, 4, 2, 1);
375 EXPECT_EQ(63, c3.Run());
376 }
377
378 // Test that currying the rvalue result of another Bind() works correctly.
379 // - rvalue should be usable as argument to Bind().
380 // - multiple runs of resulting Callback remain valid.
TEST_F(BindTest,CurryingRvalueResultOfBind)381 TEST_F(BindTest, CurryingRvalueResultOfBind) {
382 int n = 0;
383 RepeatingClosure cb = BindRepeating(&TakesACallback,
384 BindRepeating(&PtrArgSet, &n));
385
386 // If we implement Bind() such that the return value has auto_ptr-like
387 // semantics, the second call here will fail because ownership of
388 // the internal BindState<> would have been transfered to a *temporary*
389 // constructon of a Callback object on the first call.
390 cb.Run();
391 EXPECT_EQ(2, n);
392
393 n = 0;
394 cb.Run();
395 EXPECT_EQ(2, n);
396 }
397
TEST_F(BindTest,RepeatingCallbackBasicTest)398 TEST_F(BindTest, RepeatingCallbackBasicTest) {
399 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
400
401 // RepeatingCallback can run via a lvalue-reference.
402 EXPECT_EQ(63, c0.Run(32));
403
404 // It is valid to call a RepeatingCallback more than once.
405 EXPECT_EQ(54, c0.Run(23));
406
407 // BindRepeating can handle a RepeatingCallback as the target functor.
408 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
409
410 // RepeatingCallback can run via a rvalue-reference.
411 EXPECT_EQ(42, std::move(c1).Run());
412
413 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
414 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
415 }
416
TEST_F(BindTest,OnceCallbackBasicTest)417 TEST_F(BindTest, OnceCallbackBasicTest) {
418 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
419
420 // OnceCallback can run via a rvalue-reference.
421 EXPECT_EQ(63, std::move(c0).Run(32));
422
423 // After running via the rvalue-reference, the value of the OnceCallback
424 // is undefined. The implementation simply clears the instance after the
425 // invocation.
426 EXPECT_TRUE(c0.is_null());
427
428 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
429
430 // BindOnce can handle a rvalue-reference of OnceCallback as the target
431 // functor.
432 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
433 EXPECT_EQ(41, std::move(c1).Run());
434
435 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
436 EXPECT_EQ(41, BindOnce(c2, 13).Run());
437 }
438
439 // IgnoreResult adapter test.
440 // - Function with return value.
441 // - Method with return value.
442 // - Const Method with return.
443 // - Method with return value bound to WeakPtr<>.
444 // - Const Method with return bound to WeakPtr<>.
TEST_F(BindTest,IgnoreResultForRepeating)445 TEST_F(BindTest, IgnoreResultForRepeating) {
446 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
447 EXPECT_CALL(has_ref_, AddRef()).Times(2);
448 EXPECT_CALL(has_ref_, Release()).Times(2);
449 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
450 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
451 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
452 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
453
454 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
455 normal_func_cb.Run();
456
457 RepeatingClosure non_void_method_cb =
458 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
459 non_void_method_cb.Run();
460
461 RepeatingClosure non_void_const_method_cb =
462 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
463 non_void_const_method_cb.Run();
464
465 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
466 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
467
468 RepeatingClosure non_void_weak_method_cb =
469 BindRepeating(IgnoreResult(&NoRef::IntMethod0),
470 weak_factory.GetWeakPtr());
471 non_void_weak_method_cb.Run();
472
473 RepeatingClosure non_void_weak_const_method_cb =
474 BindRepeating(IgnoreResult(&NoRef::IntConstMethod0),
475 weak_factory.GetWeakPtr());
476 non_void_weak_const_method_cb.Run();
477
478 weak_factory.InvalidateWeakPtrs();
479 non_void_weak_const_method_cb.Run();
480 non_void_weak_method_cb.Run();
481 }
482
TEST_F(BindTest,IgnoreResultForOnce)483 TEST_F(BindTest, IgnoreResultForOnce) {
484 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
485 EXPECT_CALL(has_ref_, AddRef()).Times(2);
486 EXPECT_CALL(has_ref_, Release()).Times(2);
487 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
488 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
489
490 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
491 std::move(normal_func_cb).Run();
492
493 OnceClosure non_void_method_cb =
494 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
495 std::move(non_void_method_cb).Run();
496
497 OnceClosure non_void_const_method_cb =
498 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
499 std::move(non_void_const_method_cb).Run();
500
501 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
502 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
503
504 OnceClosure non_void_weak_method_cb =
505 BindOnce(IgnoreResult(&NoRef::IntMethod0),
506 weak_factory.GetWeakPtr());
507 OnceClosure non_void_weak_const_method_cb =
508 BindOnce(IgnoreResult(&NoRef::IntConstMethod0),
509 weak_factory.GetWeakPtr());
510
511 weak_factory.InvalidateWeakPtrs();
512 std::move(non_void_weak_const_method_cb).Run();
513 std::move(non_void_weak_method_cb).Run();
514 }
515
516 // Functions that take reference parameters.
517 // - Forced reference parameter type still stores a copy.
518 // - Forced const reference parameter type still stores a copy.
TEST_F(BindTest,ReferenceArgumentBindingForRepeating)519 TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
520 int n = 1;
521 int& ref_n = n;
522 const int& const_ref_n = n;
523
524 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
525 EXPECT_EQ(n, ref_copies_cb.Run());
526 n++;
527 EXPECT_EQ(n - 1, ref_copies_cb.Run());
528
529 RepeatingCallback<int()> const_ref_copies_cb =
530 BindRepeating(&Identity, const_ref_n);
531 EXPECT_EQ(n, const_ref_copies_cb.Run());
532 n++;
533 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
534 }
535
TEST_F(BindTest,ReferenceArgumentBindingForOnce)536 TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
537 int n = 1;
538 int& ref_n = n;
539 const int& const_ref_n = n;
540
541 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
542 n++;
543 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
544
545 OnceCallback<int()> const_ref_copies_cb =
546 BindOnce(&Identity, const_ref_n);
547 n++;
548 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
549 }
550
551 // Check that we can pass in arrays and have them be stored as a pointer.
552 // - Array of values stores a pointer.
553 // - Array of const values stores a pointer.
TEST_F(BindTest,ArrayArgumentBindingForRepeating)554 TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
555 int array[4] = {1, 1, 1, 1};
556 const int (*const_array_ptr)[4] = &array;
557
558 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
559 EXPECT_EQ(1, array_cb.Run());
560
561 RepeatingCallback<int()> const_array_cb =
562 BindRepeating(&ArrayGet, *const_array_ptr, 1);
563 EXPECT_EQ(1, const_array_cb.Run());
564
565 array[1] = 3;
566 EXPECT_EQ(3, array_cb.Run());
567 EXPECT_EQ(3, const_array_cb.Run());
568 }
569
TEST_F(BindTest,ArrayArgumentBindingForOnce)570 TEST_F(BindTest, ArrayArgumentBindingForOnce) {
571 int array[4] = {1, 1, 1, 1};
572 const int (*const_array_ptr)[4] = &array;
573
574 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
575 OnceCallback<int()> const_array_cb =
576 BindOnce(&ArrayGet, *const_array_ptr, 1);
577
578 array[1] = 3;
579 EXPECT_EQ(3, std::move(array_cb).Run());
580 EXPECT_EQ(3, std::move(const_array_cb).Run());
581 }
582
583 // WeakPtr() support.
584 // - Method bound to WeakPtr<> to non-const object.
585 // - Const method bound to WeakPtr<> to non-const object.
586 // - Const method bound to WeakPtr<> to const object.
587 // - Normal Function with WeakPtr<> as P1 can have return type and is
588 // not canceled.
TEST_F(BindTest,WeakPtrForRepeating)589 TEST_F(BindTest, WeakPtrForRepeating) {
590 EXPECT_CALL(no_ref_, VoidMethod0());
591 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
592
593 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
594 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
595
596 RepeatingClosure method_cb =
597 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
598 method_cb.Run();
599
600 RepeatingClosure const_method_cb =
601 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
602 const_method_cb.Run();
603
604 RepeatingClosure const_method_const_ptr_cb =
605 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
606 const_method_const_ptr_cb.Run();
607
608 RepeatingCallback<int(int)> normal_func_cb =
609 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
610 EXPECT_EQ(1, normal_func_cb.Run(1));
611
612 weak_factory.InvalidateWeakPtrs();
613 const_weak_factory.InvalidateWeakPtrs();
614
615 method_cb.Run();
616 const_method_cb.Run();
617 const_method_const_ptr_cb.Run();
618
619 // Still runs even after the pointers are invalidated.
620 EXPECT_EQ(2, normal_func_cb.Run(2));
621 }
622
TEST_F(BindTest,WeakPtrForOnce)623 TEST_F(BindTest, WeakPtrForOnce) {
624 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
625 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
626
627 OnceClosure method_cb =
628 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
629 OnceClosure const_method_cb =
630 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
631 OnceClosure const_method_const_ptr_cb =
632 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
633 Callback<int(int)> normal_func_cb =
634 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
635
636 weak_factory.InvalidateWeakPtrs();
637 const_weak_factory.InvalidateWeakPtrs();
638
639 std::move(method_cb).Run();
640 std::move(const_method_cb).Run();
641 std::move(const_method_const_ptr_cb).Run();
642
643 // Still runs even after the pointers are invalidated.
644 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
645 }
646
647 // ConstRef() wrapper support.
648 // - Binding w/o ConstRef takes a copy.
649 // - Binding a ConstRef takes a reference.
650 // - Binding ConstRef to a function ConstRef does not copy on invoke.
TEST_F(BindTest,ConstRefForRepeating)651 TEST_F(BindTest, ConstRefForRepeating) {
652 int n = 1;
653
654 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
655 RepeatingCallback<int()> const_ref_cb = BindRepeating(&Identity, ConstRef(n));
656 EXPECT_EQ(n, copy_cb.Run());
657 EXPECT_EQ(n, const_ref_cb.Run());
658 n++;
659 EXPECT_EQ(n - 1, copy_cb.Run());
660 EXPECT_EQ(n, const_ref_cb.Run());
661
662 int copies = 0;
663 int assigns = 0;
664 int move_constructs = 0;
665 int move_assigns = 0;
666 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
667 RepeatingCallback<int()> all_const_ref_cb =
668 BindRepeating(&GetCopies, ConstRef(counter));
669 EXPECT_EQ(0, all_const_ref_cb.Run());
670 EXPECT_EQ(0, copies);
671 EXPECT_EQ(0, assigns);
672 EXPECT_EQ(0, move_constructs);
673 EXPECT_EQ(0, move_assigns);
674 }
675
TEST_F(BindTest,ConstRefForOnce)676 TEST_F(BindTest, ConstRefForOnce) {
677 int n = 1;
678
679 OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
680 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, ConstRef(n));
681 n++;
682 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
683 EXPECT_EQ(n, std::move(const_ref_cb).Run());
684
685 int copies = 0;
686 int assigns = 0;
687 int move_constructs = 0;
688 int move_assigns = 0;
689 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
690 OnceCallback<int()> all_const_ref_cb =
691 BindOnce(&GetCopies, ConstRef(counter));
692 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
693 EXPECT_EQ(0, copies);
694 EXPECT_EQ(0, assigns);
695 EXPECT_EQ(0, move_constructs);
696 EXPECT_EQ(0, move_assigns);
697 }
698
699 // Test Owned() support.
TEST_F(BindTest,OwnedForRepeating)700 TEST_F(BindTest, OwnedForRepeating) {
701 int deletes = 0;
702 DeleteCounter* counter = new DeleteCounter(&deletes);
703
704 // If we don't capture, delete happens on Callback destruction/reset.
705 // return the same value.
706 RepeatingCallback<DeleteCounter*()> no_capture_cb =
707 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
708 ASSERT_EQ(counter, no_capture_cb.Run());
709 ASSERT_EQ(counter, no_capture_cb.Run());
710 EXPECT_EQ(0, deletes);
711 no_capture_cb.Reset(); // This should trigger a delete.
712 EXPECT_EQ(1, deletes);
713
714 deletes = 0;
715 counter = new DeleteCounter(&deletes);
716 RepeatingClosure own_object_cb =
717 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
718 own_object_cb.Run();
719 EXPECT_EQ(0, deletes);
720 own_object_cb.Reset();
721 EXPECT_EQ(1, deletes);
722 }
723
TEST_F(BindTest,OwnedForOnce)724 TEST_F(BindTest, OwnedForOnce) {
725 int deletes = 0;
726 DeleteCounter* counter = new DeleteCounter(&deletes);
727
728 // If we don't capture, delete happens on Callback destruction/reset.
729 // return the same value.
730 OnceCallback<DeleteCounter*()> no_capture_cb =
731 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
732 EXPECT_EQ(0, deletes);
733 no_capture_cb.Reset(); // This should trigger a delete.
734 EXPECT_EQ(1, deletes);
735
736 deletes = 0;
737 counter = new DeleteCounter(&deletes);
738 OnceClosure own_object_cb =
739 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
740 EXPECT_EQ(0, deletes);
741 own_object_cb.Reset();
742 EXPECT_EQ(1, deletes);
743 }
744
745 template <typename T>
746 class BindVariantsTest : public ::testing::Test {
747 };
748
749 struct RepeatingTestConfig {
750 template <typename Signature>
751 using CallbackType = RepeatingCallback<Signature>;
752 using ClosureType = RepeatingClosure;
753
754 template <typename F, typename... Args>
755 static CallbackType<MakeUnboundRunType<F, Args...>>
Bindbase::__anon87abc92c0111::RepeatingTestConfig756 Bind(F&& f, Args&&... args) {
757 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
758 }
759 };
760
761 struct OnceTestConfig {
762 template <typename Signature>
763 using CallbackType = OnceCallback<Signature>;
764 using ClosureType = OnceClosure;
765
766 template <typename F, typename... Args>
767 static CallbackType<MakeUnboundRunType<F, Args...>>
Bindbase::__anon87abc92c0111::OnceTestConfig768 Bind(F&& f, Args&&... args) {
769 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
770 }
771 };
772
773 using BindVariantsTestConfig = ::testing::Types<
774 RepeatingTestConfig, OnceTestConfig>;
775 TYPED_TEST_CASE(BindVariantsTest, BindVariantsTestConfig);
776
777 template <typename TypeParam, typename Signature>
778 using CallbackType = typename TypeParam::template CallbackType<Signature>;
779
780 // Function type support.
781 // - Normal function.
782 // - Normal function bound with non-refcounted first argument.
783 // - Method bound to non-const object.
784 // - Method bound to scoped_refptr.
785 // - Const method bound to non-const object.
786 // - Const method bound to const object.
787 // - Derived classes can be used with pointers to non-virtual base functions.
788 // - Derived classes can be used with pointers to virtual base functions (and
789 // preserve virtual dispatch).
TYPED_TEST(BindVariantsTest,FunctionTypeSupport)790 TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
791 using ClosureType = typename TypeParam::ClosureType;
792
793 StrictMock<HasRef> has_ref;
794 StrictMock<NoRef> no_ref;
795 StrictMock<NoRef> static_func_mock;
796 const HasRef* const_has_ref_ptr = &has_ref;
797 g_func_mock_ptr = &static_func_mock;
798
799 EXPECT_CALL(static_func_mock, VoidMethod0());
800 EXPECT_CALL(has_ref, AddRef()).Times(4);
801 EXPECT_CALL(has_ref, Release()).Times(4);
802 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
803 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
804
805 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
806 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
807 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
808 std::move(normal_cb).Run();
809 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
810
811 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
812 ClosureType method_refptr_cb = TypeParam::Bind(&HasRef::VoidMethod0,
813 make_scoped_refptr(&has_ref));
814 ClosureType const_method_nonconst_obj_cb =
815 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
816 ClosureType const_method_const_obj_cb =
817 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
818 std::move(method_cb).Run();
819 std::move(method_refptr_cb).Run();
820 std::move(const_method_nonconst_obj_cb).Run();
821 std::move(const_method_const_obj_cb).Run();
822
823 Child child;
824 child.value = 0;
825 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
826 std::move(virtual_set_cb).Run();
827 EXPECT_EQ(kChildValue, child.value);
828
829 child.value = 0;
830 ClosureType non_virtual_set_cb =
831 TypeParam::Bind(&Parent::NonVirtualSet, &child);
832 std::move(non_virtual_set_cb).Run();
833 EXPECT_EQ(kParentValue, child.value);
834 }
835
836 // Return value support.
837 // - Function with return value.
838 // - Method with return value.
839 // - Const method with return value.
840 // - Move-only return value.
TYPED_TEST(BindVariantsTest,ReturnValues)841 TYPED_TEST(BindVariantsTest, ReturnValues) {
842 StrictMock<NoRef> static_func_mock;
843 StrictMock<HasRef> has_ref;
844 g_func_mock_ptr = &static_func_mock;
845 const HasRef* const_has_ref_ptr = &has_ref;
846
847 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
848 EXPECT_CALL(has_ref, AddRef()).Times(4);
849 EXPECT_CALL(has_ref, Release()).Times(4);
850 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
851 EXPECT_CALL(has_ref, IntConstMethod0())
852 .WillOnce(Return(41337))
853 .WillOnce(Return(51337));
854 EXPECT_CALL(has_ref, UniquePtrMethod0())
855 .WillOnce(Return(ByMove(MakeUnique<int>(42))));
856
857 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
858 CallbackType<TypeParam, int()> method_cb =
859 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
860 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
861 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
862 CallbackType<TypeParam, int()> const_method_const_obj_cb =
863 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
864 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
865 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
866 EXPECT_EQ(1337, std::move(normal_cb).Run());
867 EXPECT_EQ(31337, std::move(method_cb).Run());
868 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
869 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
870 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
871 }
872
873 // Argument binding tests.
874 // - Argument binding to primitive.
875 // - Argument binding to primitive pointer.
876 // - Argument binding to a literal integer.
877 // - Argument binding to a literal string.
878 // - Argument binding with template function.
879 // - Argument binding to an object.
880 // - Argument binding to pointer to incomplete type.
881 // - Argument gets type converted.
882 // - Pointer argument gets converted.
883 // - Const Reference forces conversion.
TYPED_TEST(BindVariantsTest,ArgumentBinding)884 TYPED_TEST(BindVariantsTest, ArgumentBinding) {
885 int n = 2;
886
887 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
888 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
889 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
890 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
891 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
892
893 NoRefParent p;
894 p.value = 5;
895 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
896
897 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
898 EXPECT_EQ(incomplete_ptr,
899 TypeParam::Bind(&PolymorphicIdentity<IncompleteType*>,
900 incomplete_ptr).Run());
901
902 NoRefChild c;
903 c.value = 6;
904 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
905
906 c.value = 7;
907 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
908
909 c.value = 8;
910 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
911 }
912
913 // Unbound argument type support tests.
914 // - Unbound value.
915 // - Unbound pointer.
916 // - Unbound reference.
917 // - Unbound const reference.
918 // - Unbound unsized array.
919 // - Unbound sized array.
920 // - Unbound array-of-arrays.
TYPED_TEST(BindVariantsTest,UnboundArgumentTypeSupport)921 TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
922 CallbackType<TypeParam, void(int)> unbound_value_cb =
923 TypeParam::Bind(&VoidPolymorphic<int>::Run);
924 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
925 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
926 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
927 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
928 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
929 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
930 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
931 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
932 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
933 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
934 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
935 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
936 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
937 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
938 }
939
940 // Function with unbound reference parameter.
941 // - Original parameter is modified by callback.
TYPED_TEST(BindVariantsTest,UnboundReferenceSupport)942 TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
943 int n = 0;
944 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
945 TypeParam::Bind(&RefArgSet);
946 std::move(unbound_ref_cb).Run(n);
947 EXPECT_EQ(2, n);
948 }
949
950 // Unretained() wrapper support.
951 // - Method bound to Unretained() non-const object.
952 // - Const method bound to Unretained() non-const object.
953 // - Const method bound to Unretained() const object.
TYPED_TEST(BindVariantsTest,Unretained)954 TYPED_TEST(BindVariantsTest, Unretained) {
955 StrictMock<NoRef> no_ref;
956 const NoRef* const_no_ref_ptr = &no_ref;
957
958 EXPECT_CALL(no_ref, VoidMethod0());
959 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
960
961 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
962 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
963 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
964 }
965
TYPED_TEST(BindVariantsTest,ScopedRefptr)966 TYPED_TEST(BindVariantsTest, ScopedRefptr) {
967 StrictMock<HasRef> has_ref;
968 EXPECT_CALL(has_ref, AddRef()).Times(1);
969 EXPECT_CALL(has_ref, Release()).Times(1);
970
971 const scoped_refptr<HasRef> refptr(&has_ref);
972 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb =
973 TypeParam::Bind(&FunctionWithScopedRefptrFirstParam,
974 base::ConstRef(refptr), 1);
975 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
976 }
977
TYPED_TEST(BindVariantsTest,UniquePtrReceiver)978 TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
979 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
980 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
981 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
982 }
983
984 // Tests for Passed() wrapper support:
985 // - Passed() can be constructed from a pointer to scoper.
986 // - Passed() can be constructed from a scoper rvalue.
987 // - Using Passed() gives Callback Ownership.
988 // - Ownership is transferred from Callback to callee on the first Run().
989 // - Callback supports unbound arguments.
990 template <typename T>
991 class BindMoveOnlyTypeTest : public ::testing::Test {
992 };
993
994 struct CustomDeleter {
operator ()base::__anon87abc92c0111::CustomDeleter995 void operator()(DeleteCounter* c) { delete c; }
996 };
997
998 using MoveOnlyTypesToTest =
999 ::testing::Types<std::unique_ptr<DeleteCounter>,
1000 std::unique_ptr<DeleteCounter, CustomDeleter>>;
1001 TYPED_TEST_CASE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
1002
TYPED_TEST(BindMoveOnlyTypeTest,PassedToBoundCallback)1003 TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
1004 int deletes = 0;
1005
1006 TypeParam ptr(new DeleteCounter(&deletes));
1007 Callback<TypeParam()> callback = Bind(&PassThru<TypeParam>, Passed(&ptr));
1008 EXPECT_FALSE(ptr.get());
1009 EXPECT_EQ(0, deletes);
1010
1011 // If we never invoke the Callback, it retains ownership and deletes.
1012 callback.Reset();
1013 EXPECT_EQ(1, deletes);
1014 }
1015
TYPED_TEST(BindMoveOnlyTypeTest,PassedWithRvalue)1016 TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
1017 int deletes = 0;
1018 Callback<TypeParam()> callback = Bind(
1019 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
1020 EXPECT_EQ(0, deletes);
1021
1022 // If we never invoke the Callback, it retains ownership and deletes.
1023 callback.Reset();
1024 EXPECT_EQ(1, deletes);
1025 }
1026
1027 // Check that ownership can be transferred back out.
TYPED_TEST(BindMoveOnlyTypeTest,ReturnMoveOnlyType)1028 TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
1029 int deletes = 0;
1030 DeleteCounter* counter = new DeleteCounter(&deletes);
1031 Callback<TypeParam()> callback =
1032 Bind(&PassThru<TypeParam>, Passed(TypeParam(counter)));
1033 TypeParam result = callback.Run();
1034 ASSERT_EQ(counter, result.get());
1035 EXPECT_EQ(0, deletes);
1036
1037 // Resetting does not delete since ownership was transferred.
1038 callback.Reset();
1039 EXPECT_EQ(0, deletes);
1040
1041 // Ensure that we actually did get ownership.
1042 result.reset();
1043 EXPECT_EQ(1, deletes);
1044 }
1045
TYPED_TEST(BindMoveOnlyTypeTest,UnboundForwarding)1046 TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
1047 int deletes = 0;
1048 TypeParam ptr(new DeleteCounter(&deletes));
1049 // Test unbound argument forwarding.
1050 Callback<TypeParam(TypeParam)> cb_unbound = Bind(&PassThru<TypeParam>);
1051 cb_unbound.Run(std::move(ptr));
1052 EXPECT_EQ(1, deletes);
1053 }
1054
VerifyVector(const std::vector<std::unique_ptr<int>> & v)1055 void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
1056 ASSERT_EQ(1u, v.size());
1057 EXPECT_EQ(12345, *v[0]);
1058 }
1059
AcceptAndReturnMoveOnlyVector(std::vector<std::unique_ptr<int>> v)1060 std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
1061 std::vector<std::unique_ptr<int>> v) {
1062 VerifyVector(v);
1063 return v;
1064 }
1065
1066 // Test that a vector containing move-only types can be used with Callback.
TEST_F(BindTest,BindMoveOnlyVector)1067 TEST_F(BindTest, BindMoveOnlyVector) {
1068 using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
1069
1070 MoveOnlyVector v;
1071 v.push_back(WrapUnique(new int(12345)));
1072
1073 // Early binding should work:
1074 base::Callback<MoveOnlyVector()> bound_cb =
1075 base::Bind(&AcceptAndReturnMoveOnlyVector, Passed(&v));
1076 MoveOnlyVector intermediate_result = bound_cb.Run();
1077 VerifyVector(intermediate_result);
1078
1079 // As should passing it as an argument to Run():
1080 base::Callback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
1081 base::Bind(&AcceptAndReturnMoveOnlyVector);
1082 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
1083 VerifyVector(final_result);
1084 }
1085
1086 // Argument copy-constructor usage for non-reference copy-only parameters.
1087 // - Bound arguments are only copied once.
1088 // - Forwarded arguments are only copied once.
1089 // - Forwarded arguments with coercions are only copied twice (once for the
1090 // coercion, and one for the final dispatch).
TEST_F(BindTest,ArgumentCopies)1091 TEST_F(BindTest, ArgumentCopies) {
1092 int copies = 0;
1093 int assigns = 0;
1094
1095 CopyCounter counter(&copies, &assigns);
1096 Bind(&VoidPolymorphic<CopyCounter>::Run, counter);
1097 EXPECT_EQ(1, copies);
1098 EXPECT_EQ(0, assigns);
1099
1100 copies = 0;
1101 assigns = 0;
1102 Bind(&VoidPolymorphic<CopyCounter>::Run, CopyCounter(&copies, &assigns));
1103 EXPECT_EQ(1, copies);
1104 EXPECT_EQ(0, assigns);
1105
1106 copies = 0;
1107 assigns = 0;
1108 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
1109 EXPECT_EQ(2, copies);
1110 EXPECT_EQ(0, assigns);
1111
1112 copies = 0;
1113 assigns = 0;
1114 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(&copies, &assigns));
1115 EXPECT_EQ(1, copies);
1116 EXPECT_EQ(0, assigns);
1117
1118 copies = 0;
1119 assigns = 0;
1120 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
1121 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
1122 EXPECT_EQ(2, copies);
1123 EXPECT_EQ(0, assigns);
1124
1125 copies = 0;
1126 assigns = 0;
1127 Bind(&VoidPolymorphic<CopyCounter>::Run)
1128 .Run(CopyCounter(
1129 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
1130 EXPECT_EQ(2, copies);
1131 EXPECT_EQ(0, assigns);
1132 }
1133
1134 // Argument move-constructor usage for move-only parameters.
1135 // - Bound arguments passed by move are not copied.
TEST_F(BindTest,ArgumentMoves)1136 TEST_F(BindTest, ArgumentMoves) {
1137 int move_constructs = 0;
1138 int move_assigns = 0;
1139
1140 Bind(&VoidPolymorphic<const MoveCounter&>::Run,
1141 MoveCounter(&move_constructs, &move_assigns));
1142 EXPECT_EQ(1, move_constructs);
1143 EXPECT_EQ(0, move_assigns);
1144
1145 // TODO(tzik): Support binding move-only type into a non-reference parameter
1146 // of a variant of Callback.
1147
1148 move_constructs = 0;
1149 move_assigns = 0;
1150 Bind(&VoidPolymorphic<MoveCounter>::Run)
1151 .Run(MoveCounter(&move_constructs, &move_assigns));
1152 EXPECT_EQ(1, move_constructs);
1153 EXPECT_EQ(0, move_assigns);
1154
1155 move_constructs = 0;
1156 move_assigns = 0;
1157 Bind(&VoidPolymorphic<MoveCounter>::Run)
1158 .Run(MoveCounter(DerivedCopyMoveCounter(
1159 nullptr, nullptr, &move_constructs, &move_assigns)));
1160 EXPECT_EQ(2, move_constructs);
1161 EXPECT_EQ(0, move_assigns);
1162 }
1163
1164 // Argument constructor usage for non-reference movable-copyable
1165 // parameters.
1166 // - Bound arguments passed by move are not copied.
1167 // - Forwarded arguments are only copied once.
1168 // - Forwarded arguments with coercions are only copied once and moved once.
TEST_F(BindTest,ArgumentCopiesAndMoves)1169 TEST_F(BindTest, ArgumentCopiesAndMoves) {
1170 int copies = 0;
1171 int assigns = 0;
1172 int move_constructs = 0;
1173 int move_assigns = 0;
1174
1175 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
1176 Bind(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
1177 EXPECT_EQ(1, copies);
1178 EXPECT_EQ(0, assigns);
1179 EXPECT_EQ(0, move_constructs);
1180 EXPECT_EQ(0, move_assigns);
1181
1182 copies = 0;
1183 assigns = 0;
1184 move_constructs = 0;
1185 move_assigns = 0;
1186 Bind(&VoidPolymorphic<CopyMoveCounter>::Run,
1187 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1188 EXPECT_EQ(0, copies);
1189 EXPECT_EQ(0, assigns);
1190 EXPECT_EQ(1, move_constructs);
1191 EXPECT_EQ(0, move_assigns);
1192
1193 copies = 0;
1194 assigns = 0;
1195 move_constructs = 0;
1196 move_assigns = 0;
1197 Bind(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter);
1198 EXPECT_EQ(1, copies);
1199 EXPECT_EQ(0, assigns);
1200 EXPECT_EQ(1, move_constructs);
1201 EXPECT_EQ(0, move_assigns);
1202
1203 copies = 0;
1204 assigns = 0;
1205 move_constructs = 0;
1206 move_assigns = 0;
1207 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1208 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1209 EXPECT_EQ(0, copies);
1210 EXPECT_EQ(0, assigns);
1211 EXPECT_EQ(1, move_constructs);
1212 EXPECT_EQ(0, move_assigns);
1213
1214 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1215 &move_assigns);
1216 copies = 0;
1217 assigns = 0;
1218 move_constructs = 0;
1219 move_assigns = 0;
1220 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1221 .Run(CopyMoveCounter(derived_counter));
1222 EXPECT_EQ(1, copies);
1223 EXPECT_EQ(0, assigns);
1224 EXPECT_EQ(1, move_constructs);
1225 EXPECT_EQ(0, move_assigns);
1226
1227 copies = 0;
1228 assigns = 0;
1229 move_constructs = 0;
1230 move_assigns = 0;
1231 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1232 .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1233 &copies, &assigns, &move_constructs, &move_assigns)));
1234 EXPECT_EQ(0, copies);
1235 EXPECT_EQ(0, assigns);
1236 EXPECT_EQ(2, move_constructs);
1237 EXPECT_EQ(0, move_assigns);
1238 }
1239
TEST_F(BindTest,CapturelessLambda)1240 TEST_F(BindTest, CapturelessLambda) {
1241 EXPECT_FALSE(internal::IsConvertibleToRunType<void>::value);
1242 EXPECT_FALSE(internal::IsConvertibleToRunType<int>::value);
1243 EXPECT_FALSE(internal::IsConvertibleToRunType<void(*)()>::value);
1244 EXPECT_FALSE(internal::IsConvertibleToRunType<void(NoRef::*)()>::value);
1245
1246 auto f = []() {};
1247 EXPECT_TRUE(internal::IsConvertibleToRunType<decltype(f)>::value);
1248
1249 int i = 0;
1250 auto g = [i]() { (void)i; };
1251 EXPECT_FALSE(internal::IsConvertibleToRunType<decltype(g)>::value);
1252
1253 auto h = [](int, double) { return 'k'; };
1254 EXPECT_TRUE((std::is_same<
1255 char(int, double),
1256 internal::ExtractCallableRunType<decltype(h)>>::value));
1257
1258 EXPECT_EQ(42, Bind([] { return 42; }).Run());
1259 EXPECT_EQ(42, Bind([](int i) { return i * 7; }, 6).Run());
1260
1261 int x = 1;
1262 base::Callback<void(int)> cb =
1263 Bind([](int* x, int i) { *x *= i; }, Unretained(&x));
1264 cb.Run(6);
1265 EXPECT_EQ(6, x);
1266 cb.Run(7);
1267 EXPECT_EQ(42, x);
1268 }
1269
TEST_F(BindTest,Cancellation)1270 TEST_F(BindTest, Cancellation) {
1271 EXPECT_CALL(no_ref_, VoidMethodWithIntArg(_)).Times(2);
1272
1273 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
1274 RepeatingCallback<void(int)> cb =
1275 BindRepeating(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1276 RepeatingClosure cb2 = BindRepeating(cb, 8);
1277 OnceClosure cb3 = BindOnce(cb, 8);
1278
1279 OnceCallback<void(int)> cb4 =
1280 BindOnce(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1281 EXPECT_FALSE(cb4.IsCancelled());
1282
1283 OnceClosure cb5 = BindOnce(std::move(cb4), 8);
1284
1285 EXPECT_FALSE(cb.IsCancelled());
1286 EXPECT_FALSE(cb2.IsCancelled());
1287 EXPECT_FALSE(cb3.IsCancelled());
1288 EXPECT_FALSE(cb5.IsCancelled());
1289
1290 cb.Run(6);
1291 cb2.Run();
1292
1293 weak_factory.InvalidateWeakPtrs();
1294
1295 EXPECT_TRUE(cb.IsCancelled());
1296 EXPECT_TRUE(cb2.IsCancelled());
1297 EXPECT_TRUE(cb3.IsCancelled());
1298 EXPECT_TRUE(cb5.IsCancelled());
1299
1300 cb.Run(6);
1301 cb2.Run();
1302 std::move(cb3).Run();
1303 std::move(cb5).Run();
1304 }
1305
TEST_F(BindTest,OnceCallback)1306 TEST_F(BindTest, OnceCallback) {
1307 // Check if Callback variants have declarations of conversions as expected.
1308 // Copy constructor and assignment of RepeatingCallback.
1309 static_assert(std::is_constructible<
1310 RepeatingClosure, const RepeatingClosure&>::value,
1311 "RepeatingClosure should be copyable.");
1312 static_assert(
1313 std::is_assignable<RepeatingClosure, const RepeatingClosure&>::value,
1314 "RepeatingClosure should be copy-assignable.");
1315
1316 // Move constructor and assignment of RepeatingCallback.
1317 static_assert(std::is_constructible<
1318 RepeatingClosure, RepeatingClosure&&>::value,
1319 "RepeatingClosure should be movable.");
1320 static_assert(std::is_assignable<RepeatingClosure, RepeatingClosure&&>::value,
1321 "RepeatingClosure should be move-assignable");
1322
1323 // Conversions from OnceCallback to RepeatingCallback.
1324 static_assert(!std::is_constructible<
1325 RepeatingClosure, const OnceClosure&>::value,
1326 "OnceClosure should not be convertible to RepeatingClosure.");
1327 static_assert(
1328 !std::is_assignable<RepeatingClosure, const OnceClosure&>::value,
1329 "OnceClosure should not be convertible to RepeatingClosure.");
1330
1331 // Destructive conversions from OnceCallback to RepeatingCallback.
1332 static_assert(!std::is_constructible<
1333 RepeatingClosure, OnceClosure&&>::value,
1334 "OnceClosure should not be convertible to RepeatingClosure.");
1335 static_assert(!std::is_assignable<RepeatingClosure, OnceClosure&&>::value,
1336 "OnceClosure should not be convertible to RepeatingClosure.");
1337
1338 // Copy constructor and assignment of OnceCallback.
1339 static_assert(!std::is_constructible<
1340 OnceClosure, const OnceClosure&>::value,
1341 "OnceClosure should not be copyable.");
1342 static_assert(!std::is_assignable<OnceClosure, const OnceClosure&>::value,
1343 "OnceClosure should not be copy-assignable");
1344
1345 // Move constructor and assignment of OnceCallback.
1346 static_assert(std::is_constructible<
1347 OnceClosure, OnceClosure&&>::value,
1348 "OnceClosure should be movable.");
1349 static_assert(std::is_assignable<OnceClosure, OnceClosure&&>::value,
1350 "OnceClosure should be move-assignable.");
1351
1352 // Conversions from RepeatingCallback to OnceCallback.
1353 static_assert(std::is_constructible<
1354 OnceClosure, const RepeatingClosure&>::value,
1355 "RepeatingClosure should be convertible to OnceClosure.");
1356 static_assert(std::is_assignable<OnceClosure, const RepeatingClosure&>::value,
1357 "RepeatingClosure should be convertible to OnceClosure.");
1358
1359 // Destructive conversions from RepeatingCallback to OnceCallback.
1360 static_assert(std::is_constructible<
1361 OnceClosure, RepeatingClosure&&>::value,
1362 "RepeatingClosure should be convertible to OnceClosure.");
1363 static_assert(std::is_assignable<OnceClosure, RepeatingClosure&&>::value,
1364 "RepeatingClosure should be covretible to OnceClosure.");
1365
1366 OnceClosure cb = BindOnce(&VoidPolymorphic<>::Run);
1367 std::move(cb).Run();
1368
1369 // RepeatingCallback should be convertible to OnceCallback.
1370 OnceClosure cb2 = BindRepeating(&VoidPolymorphic<>::Run);
1371 std::move(cb2).Run();
1372
1373 RepeatingClosure cb3 = BindRepeating(&VoidPolymorphic<>::Run);
1374 cb = cb3;
1375 std::move(cb).Run();
1376
1377 cb = std::move(cb2);
1378
1379 OnceCallback<void(int)> cb4 = BindOnce(
1380 &VoidPolymorphic<std::unique_ptr<int>, int>::Run, MakeUnique<int>(0));
1381 BindOnce(std::move(cb4), 1).Run();
1382 }
1383
1384 // Callback construction and assignment tests.
1385 // - Construction from an InvokerStorageHolder should not cause ref/deref.
1386 // - Assignment from other callback should only cause one ref
1387 //
1388 // TODO(ajwong): Is there actually a way to test this?
1389
1390 #if defined(OS_WIN)
FastCallFunc(int n)1391 int __fastcall FastCallFunc(int n) {
1392 return n;
1393 }
1394
StdCallFunc(int n)1395 int __stdcall StdCallFunc(int n) {
1396 return n;
1397 }
1398
1399 // Windows specific calling convention support.
1400 // - Can bind a __fastcall function.
1401 // - Can bind a __stdcall function.
TEST_F(BindTest,WindowsCallingConventions)1402 TEST_F(BindTest, WindowsCallingConventions) {
1403 Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1);
1404 EXPECT_EQ(1, fastcall_cb.Run());
1405
1406 Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2);
1407 EXPECT_EQ(2, stdcall_cb.Run());
1408 }
1409 #endif
1410
1411 // Test null callbacks cause a DCHECK.
TEST(BindDeathTest,NullCallback)1412 TEST(BindDeathTest, NullCallback) {
1413 base::Callback<void(int)> null_cb;
1414 ASSERT_TRUE(null_cb.is_null());
1415 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42));
1416 }
1417
1418 } // namespace
1419 } // namespace base
1420