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