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