blob: 88b1fff5b8573e851e277a00608be752c3d5509b [file] [log] [blame]
[email protected]44106182012-04-06 03:53:021// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]b38d3572011-02-15 01:27:382// 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
dcheng69f2a042015-12-14 20:31:527#include <memory>
8#include <utility>
dcheng53b4cea2016-02-02 04:09:339#include <vector>
dcheng69f2a042015-12-14 20:31:5210
[email protected]b38d3572011-02-15 01:27:3811#include "base/callback.h"
avi9b6f42932015-12-26 22:15:1412#include "base/macros.h"
dcheng093de9b2016-04-04 21:25:5113#include "base/memory/ptr_util.h"
[email protected]206a2ae82011-12-22 21:12:5814#include "base/memory/ref_counted.h"
[email protected]206a2ae82011-12-22 21:12:5815#include "base/memory/weak_ptr.h"
gabc964a852016-08-01 16:39:5616#include "base/test/gtest_util.h"
avi9b6f42932015-12-26 22:15:1417#include "build/build_config.h"
[email protected]b38d3572011-02-15 01:27:3818#include "testing/gmock/include/gmock/gmock.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
dcheng172b6ad2016-09-24 05:05:5721using ::testing::_;
[email protected]b38d3572011-02-15 01:27:3822using ::testing::Mock;
tzikb9499fd92016-10-12 04:55:0223using ::testing::ByMove;
[email protected]b38d3572011-02-15 01:27:3824using ::testing::Return;
25using ::testing::StrictMock;
26
27namespace base {
tzik44adf072016-10-07 04:34:5428
29using internal::OnceCallback;
30using internal::RepeatingCallback;
31using internal::OnceClosure;
32using internal::RepeatingClosure;
33using internal::BindOnce;
34using internal::BindRepeating;
35
[email protected]b38d3572011-02-15 01:27:3836namespace {
37
[email protected]8217d4542011-10-01 06:31:4138class IncompleteType;
39
[email protected]b38d3572011-02-15 01:27:3840class NoRef {
41 public:
42 NoRef() {}
43
tzik3bc7779b2015-12-19 09:18:4644 MOCK_METHOD0(VoidMethod0, void());
45 MOCK_CONST_METHOD0(VoidConstMethod0, void());
[email protected]b38d3572011-02-15 01:27:3846
tzik3bc7779b2015-12-19 09:18:4647 MOCK_METHOD0(IntMethod0, int());
48 MOCK_CONST_METHOD0(IntConstMethod0, int());
[email protected]b38d3572011-02-15 01:27:3849
dcheng172b6ad2016-09-24 05:05:5750 MOCK_METHOD1(VoidMethodWithIntArg, void(int));
tzikb9499fd92016-10-12 04:55:0251 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
dcheng172b6ad2016-09-24 05:05:5752
[email protected]b38d3572011-02-15 01:27:3853 private:
54 // Particularly important in this test to ensure no copies are made.
55 DISALLOW_COPY_AND_ASSIGN(NoRef);
56};
57
58class HasRef : public NoRef {
59 public:
60 HasRef() {}
61
tzik3bc7779b2015-12-19 09:18:4662 MOCK_CONST_METHOD0(AddRef, void());
63 MOCK_CONST_METHOD0(Release, bool());
[email protected]b38d3572011-02-15 01:27:3864
65 private:
66 // Particularly important in this test to ensure no copies are made.
67 DISALLOW_COPY_AND_ASSIGN(HasRef);
68};
69
[email protected]690bda882011-04-13 22:40:4670class HasRefPrivateDtor : public HasRef {
71 private:
72 ~HasRefPrivateDtor() {}
73};
74
[email protected]b38d3572011-02-15 01:27:3875static const int kParentValue = 1;
76static const int kChildValue = 2;
77
78class Parent {
79 public:
tzik3bc7779b2015-12-19 09:18:4680 void AddRef() const {}
81 void Release() const {}
[email protected]b38d3572011-02-15 01:27:3882 virtual void VirtualSet() { value = kParentValue; }
83 void NonVirtualSet() { value = kParentValue; }
84 int value;
85};
86
87class Child : public Parent {
88 public:
dcheng56488182014-10-21 10:54:5189 void VirtualSet() override { value = kChildValue; }
[email protected]b38d3572011-02-15 01:27:3890 void NonVirtualSet() { value = kChildValue; }
91};
92
93class NoRefParent {
94 public:
95 virtual void VirtualSet() { value = kParentValue; }
96 void NonVirtualSet() { value = kParentValue; }
97 int value;
98};
99
100class NoRefChild : public NoRefParent {
dcheng56488182014-10-21 10:54:51101 void VirtualSet() override { value = kChildValue; }
[email protected]b38d3572011-02-15 01:27:38102 void NonVirtualSet() { value = kChildValue; }
103};
104
tzik52dcd672016-02-15 11:54:30105// Used for probing the number of copies and moves that occur if a type must be
106// coerced during argument forwarding in the Run() methods.
107struct DerivedCopyMoveCounter {
108 DerivedCopyMoveCounter(int* copies,
109 int* assigns,
110 int* move_constructs,
111 int* move_assigns)
112 : copies_(copies),
113 assigns_(assigns),
114 move_constructs_(move_constructs),
115 move_assigns_(move_assigns) {}
[email protected]b38d3572011-02-15 01:27:38116 int* copies_;
117 int* assigns_;
tzik52dcd672016-02-15 11:54:30118 int* move_constructs_;
119 int* move_assigns_;
[email protected]b38d3572011-02-15 01:27:38120};
121
tzik52dcd672016-02-15 11:54:30122// Used for probing the number of copies and moves in an argument.
123class CopyMoveCounter {
[email protected]b38d3572011-02-15 01:27:38124 public:
tzik52dcd672016-02-15 11:54:30125 CopyMoveCounter(int* copies,
126 int* assigns,
127 int* move_constructs,
128 int* move_assigns)
129 : copies_(copies),
130 assigns_(assigns),
131 move_constructs_(move_constructs),
132 move_assigns_(move_assigns) {}
133
134 CopyMoveCounter(const CopyMoveCounter& other)
135 : copies_(other.copies_),
136 assigns_(other.assigns_),
137 move_constructs_(other.move_constructs_),
138 move_assigns_(other.move_assigns_) {
139 (*copies_)++;
[email protected]b38d3572011-02-15 01:27:38140 }
141
tzik52dcd672016-02-15 11:54:30142 CopyMoveCounter(CopyMoveCounter&& other)
[email protected]b38d3572011-02-15 01:27:38143 : copies_(other.copies_),
tzik52dcd672016-02-15 11:54:30144 assigns_(other.assigns_),
145 move_constructs_(other.move_constructs_),
146 move_assigns_(other.move_assigns_) {
147 (*move_constructs_)++;
[email protected]b38d3572011-02-15 01:27:38148 }
149
[email protected]206a2ae82011-12-22 21:12:58150 // Probing for copies from coercion.
tzik52dcd672016-02-15 11:54:30151 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
[email protected]b38d3572011-02-15 01:27:38152 : copies_(other.copies_),
tzik52dcd672016-02-15 11:54:30153 assigns_(other.assigns_),
154 move_constructs_(other.move_constructs_),
155 move_assigns_(other.move_assigns_) {
[email protected]b38d3572011-02-15 01:27:38156 (*copies_)++;
157 }
158
tzik52dcd672016-02-15 11:54:30159 // Probing for moves from coercion.
160 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
161 : copies_(other.copies_),
162 assigns_(other.assigns_),
163 move_constructs_(other.move_constructs_),
164 move_assigns_(other.move_assigns_) {
165 (*move_constructs_)++;
166 }
167
168 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
[email protected]b38d3572011-02-15 01:27:38169 copies_ = rhs.copies_;
170 assigns_ = rhs.assigns_;
tzik52dcd672016-02-15 11:54:30171 move_constructs_ = rhs.move_constructs_;
172 move_assigns_ = rhs.move_assigns_;
[email protected]b38d3572011-02-15 01:27:38173
tzik52dcd672016-02-15 11:54:30174 (*assigns_)++;
175
176 return *this;
177 }
178
179 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
180 copies_ = rhs.copies_;
181 assigns_ = rhs.assigns_;
182 move_constructs_ = rhs.move_constructs_;
183 move_assigns_ = rhs.move_assigns_;
184
185 (*move_assigns_)++;
[email protected]b38d3572011-02-15 01:27:38186
187 return *this;
188 }
189
190 int copies() const {
191 return *copies_;
192 }
193
[email protected]b38d3572011-02-15 01:27:38194 private:
195 int* copies_;
196 int* assigns_;
tzik52dcd672016-02-15 11:54:30197 int* move_constructs_;
198 int* move_assigns_;
199};
200
201// Used for probing the number of copies in an argument. The instance is a
202// copyable and non-movable type.
203class CopyCounter {
204 public:
205 CopyCounter(int* copies, int* assigns)
206 : counter_(copies, assigns, nullptr, nullptr) {}
207 CopyCounter(const CopyCounter& other) : counter_(other.counter_) {}
208 CopyCounter& operator=(const CopyCounter& other) {
209 counter_ = other.counter_;
210 return *this;
211 }
212
213 explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {}
214
215 int copies() const { return counter_.copies(); }
216
217 private:
218 CopyMoveCounter counter_;
219};
220
221// Used for probing the number of moves in an argument. The instance is a
222// non-copyable and movable type.
223class MoveCounter {
224 public:
225 MoveCounter(int* move_constructs, int* move_assigns)
226 : counter_(nullptr, nullptr, move_constructs, move_assigns) {}
227 MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {}
228 MoveCounter& operator=(MoveCounter&& other) {
229 counter_ = std::move(other.counter_);
230 return *this;
231 }
232
233 explicit MoveCounter(DerivedCopyMoveCounter&& other)
234 : counter_(std::move(other)) {}
235
236 private:
237 CopyMoveCounter counter_;
[email protected]b38d3572011-02-15 01:27:38238};
239
[email protected]08aa4552011-10-15 00:34:42240class DeleteCounter {
241 public:
242 explicit DeleteCounter(int* deletes)
243 : deletes_(deletes) {
244 }
245
246 ~DeleteCounter() {
247 (*deletes_)++;
248 }
249
250 void VoidMethod0() {}
251
252 private:
253 int* deletes_;
254};
255
[email protected]206a2ae82011-12-22 21:12:58256template <typename T>
257T PassThru(T scoper) {
dcheng69f2a042015-12-14 20:31:52258 return scoper;
[email protected]206a2ae82011-12-22 21:12:58259}
260
[email protected]b38d3572011-02-15 01:27:38261// Some test functions that we can Bind to.
262template <typename T>
263T PolymorphicIdentity(T t) {
264 return t;
265}
266
tzik7fe3a682015-12-18 02:23:26267template <typename... Ts>
268struct VoidPolymorphic {
269 static void Run(Ts... t) {}
270};
[email protected]b38d3572011-02-15 01:27:38271
272int Identity(int n) {
273 return n;
274}
275
276int ArrayGet(const int array[], int n) {
277 return array[n];
278}
279
280int Sum(int a, int b, int c, int d, int e, int f) {
281 return a + b + c + d + e + f;
282}
283
284const char* CStringIdentity(const char* s) {
285 return s;
286}
287
tzik52dcd672016-02-15 11:54:30288int GetCopies(const CopyMoveCounter& counter) {
[email protected]b38d3572011-02-15 01:27:38289 return counter.copies();
290}
291
292int UnwrapNoRefParent(NoRefParent p) {
293 return p.value;
294}
295
296int UnwrapNoRefParentPtr(NoRefParent* p) {
297 return p->value;
298}
299
300int UnwrapNoRefParentConstRef(const NoRefParent& p) {
301 return p.value;
302}
303
[email protected]c18b1052011-03-24 02:02:17304void RefArgSet(int &n) {
305 n = 2;
306}
307
[email protected]e24f8762011-12-20 00:10:04308void PtrArgSet(int *n) {
309 *n = 2;
310}
311
[email protected]93540582011-05-16 22:35:14312int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
313 return n;
314}
315
[email protected]edd2f1b2013-06-22 20:32:50316int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
317 return n;
318}
319
[email protected]e24f8762011-12-20 00:10:04320void TakesACallback(const Closure& callback) {
321 callback.Run();
322}
323
[email protected]b38d3572011-02-15 01:27:38324class BindTest : public ::testing::Test {
325 public:
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 virtual ~BindTest() {
333 }
334
tzik3bc7779b2015-12-19 09:18:46335 static void VoidFunc0() {
[email protected]b38d3572011-02-15 01:27:38336 static_func_mock_ptr->VoidMethod0();
337 }
338
tzik3bc7779b2015-12-19 09:18:46339 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
[email protected]b38d3572011-02-15 01:27:38340
341 protected:
342 StrictMock<NoRef> no_ref_;
343 StrictMock<HasRef> has_ref_;
344 const HasRef* const_has_ref_ptr_;
345 const NoRef* const_no_ref_ptr_;
346 StrictMock<NoRef> static_func_mock_;
347
348 // Used by the static functions to perform expectations.
349 static StrictMock<NoRef>* static_func_mock_ptr;
350
351 private:
352 DISALLOW_COPY_AND_ASSIGN(BindTest);
353};
354
355StrictMock<NoRef>* BindTest::static_func_mock_ptr;
tzikb9499fd92016-10-12 04:55:02356StrictMock<NoRef>* g_func_mock_ptr;
357
358void VoidFunc0() {
359 g_func_mock_ptr->VoidMethod0();
360}
361
362int IntFunc0() {
363 return g_func_mock_ptr->IntMethod0();
364}
[email protected]b38d3572011-02-15 01:27:38365
tzik4d4da502016-08-23 04:23:49366TEST_F(BindTest, BasicTest) {
367 Callback<int(int, int, int)> cb = Bind(&Sum, 32, 16, 8);
368 EXPECT_EQ(92, cb.Run(13, 12, 11));
[email protected]b38d3572011-02-15 01:27:38369
tzik4d4da502016-08-23 04:23:49370 Callback<int(int, int, int, int, int, int)> c1 = Bind(&Sum);
371 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
[email protected]b38d3572011-02-15 01:27:38372
tzik4d4da502016-08-23 04:23:49373 Callback<int(int, int, int)> c2 = Bind(c1, 32, 16, 8);
374 EXPECT_EQ(86, c2.Run(11, 10, 9));
[email protected]b38d3572011-02-15 01:27:38375
tzik4d4da502016-08-23 04:23:49376 Callback<int()> c3 = Bind(c2, 4, 2, 1);
377 EXPECT_EQ(63, c3.Run());
[email protected]cea20fe42011-09-30 09:09:34378}
379
[email protected]e24f8762011-12-20 00:10:04380// Test that currying the rvalue result of another Bind() works correctly.
381// - rvalue should be usable as argument to Bind().
382// - multiple runs of resulting Callback remain valid.
383TEST_F(BindTest, CurryingRvalueResultOfBind) {
384 int n = 0;
tzikb9499fd92016-10-12 04:55:02385 RepeatingClosure cb = BindRepeating(&TakesACallback,
386 BindRepeating(&PtrArgSet, &n));
[email protected]e24f8762011-12-20 00:10:04387
388 // If we implement Bind() such that the return value has auto_ptr-like
389 // semantics, the second call here will fail because ownership of
390 // the internal BindState<> would have been transfered to a *temporary*
391 // constructon of a Callback object on the first call.
392 cb.Run();
393 EXPECT_EQ(2, n);
394
395 n = 0;
396 cb.Run();
397 EXPECT_EQ(2, n);
398}
399
tzikb9499fd92016-10-12 04:55:02400TEST_F(BindTest, RepeatingCallbackBasicTest) {
401 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
[email protected]b38d3572011-02-15 01:27:38402
tzikb9499fd92016-10-12 04:55:02403 // RepeatingCallback can run via a lvalue-reference.
404 EXPECT_EQ(63, c0.Run(32));
[email protected]81814bce2011-09-10 03:03:00405
tzikb9499fd92016-10-12 04:55:02406 // It is valid to call a RepeatingCallback more than once.
407 EXPECT_EQ(54, c0.Run(23));
[email protected]b38d3572011-02-15 01:27:38408
tzikb9499fd92016-10-12 04:55:02409 // BindRepeating can handle a RepeatingCallback as the target functor.
410 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
[email protected]b38d3572011-02-15 01:27:38411
tzikb9499fd92016-10-12 04:55:02412 // RepeatingCallback can run via a rvalue-reference.
413 EXPECT_EQ(42, std::move(c1).Run());
414
415 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
416 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
[email protected]b38d3572011-02-15 01:27:38417}
418
tzikb9499fd92016-10-12 04:55:02419TEST_F(BindTest, OnceCallbackBasicTest) {
420 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
[email protected]b38d3572011-02-15 01:27:38421
tzikb9499fd92016-10-12 04:55:02422 // OnceCallback can run via a rvalue-reference.
423 EXPECT_EQ(63, std::move(c0).Run(32));
424
425 // After running via the rvalue-reference, the value of the OnceCallback
426 // is undefined. The implementation simply clears the instance after the
427 // invocation.
428 EXPECT_TRUE(c0.is_null());
429
430 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
431
432 // BindOnce can handle a rvalue-reference of OnceCallback as the target
433 // functor.
434 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
435 EXPECT_EQ(41, std::move(c1).Run());
436
437 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
438 EXPECT_EQ(41, BindOnce(c2, 13).Run());
[email protected]b38d3572011-02-15 01:27:38439}
440
[email protected]7296f2762011-11-21 19:23:44441// IgnoreResult adapter test.
442// - Function with return value.
443// - Method with return value.
444// - Const Method with return.
445// - Method with return value bound to WeakPtr<>.
446// - Const Method with return bound to WeakPtr<>.
tzikb9499fd92016-10-12 04:55:02447TEST_F(BindTest, IgnoreResultForRepeating) {
[email protected]e8bfc31d2011-09-28 00:26:37448 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
[email protected]7296f2762011-11-21 19:23:44449 EXPECT_CALL(has_ref_, AddRef()).Times(2);
450 EXPECT_CALL(has_ref_, Release()).Times(2);
451 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
452 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
453 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
454 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
455
tzikb9499fd92016-10-12 04:55:02456 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
[email protected]7296f2762011-11-21 19:23:44457 normal_func_cb.Run();
458
tzikb9499fd92016-10-12 04:55:02459 RepeatingClosure non_void_method_cb =
460 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
[email protected]7296f2762011-11-21 19:23:44461 non_void_method_cb.Run();
462
tzikb9499fd92016-10-12 04:55:02463 RepeatingClosure non_void_const_method_cb =
464 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
[email protected]7296f2762011-11-21 19:23:44465 non_void_const_method_cb.Run();
466
467 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
468 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
469
tzikb9499fd92016-10-12 04:55:02470 RepeatingClosure non_void_weak_method_cb =
471 BindRepeating(IgnoreResult(&NoRef::IntMethod0),
472 weak_factory.GetWeakPtr());
[email protected]7296f2762011-11-21 19:23:44473 non_void_weak_method_cb.Run();
474
tzikb9499fd92016-10-12 04:55:02475 RepeatingClosure non_void_weak_const_method_cb =
476 BindRepeating(IgnoreResult(&NoRef::IntConstMethod0),
477 weak_factory.GetWeakPtr());
[email protected]7296f2762011-11-21 19:23:44478 non_void_weak_const_method_cb.Run();
479
480 weak_factory.InvalidateWeakPtrs();
481 non_void_weak_const_method_cb.Run();
482 non_void_weak_method_cb.Run();
[email protected]e8bfc31d2011-09-28 00:26:37483}
484
tzikb9499fd92016-10-12 04:55:02485TEST_F(BindTest, IgnoreResultForOnce) {
486 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
487 EXPECT_CALL(has_ref_, AddRef()).Times(2);
488 EXPECT_CALL(has_ref_, Release()).Times(2);
489 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
490 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
[email protected]b38d3572011-02-15 01:27:38491
tzikb9499fd92016-10-12 04:55:02492 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
493 std::move(normal_func_cb).Run();
[email protected]b38d3572011-02-15 01:27:38494
tzikb9499fd92016-10-12 04:55:02495 OnceClosure non_void_method_cb =
496 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
497 std::move(non_void_method_cb).Run();
[email protected]b38d3572011-02-15 01:27:38498
tzikb9499fd92016-10-12 04:55:02499 OnceClosure non_void_const_method_cb =
500 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
501 std::move(non_void_const_method_cb).Run();
[email protected]b38d3572011-02-15 01:27:38502
tzikb9499fd92016-10-12 04:55:02503 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
504 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
[email protected]b38d3572011-02-15 01:27:38505
tzikb9499fd92016-10-12 04:55:02506 OnceClosure non_void_weak_method_cb =
507 BindOnce(IgnoreResult(&NoRef::IntMethod0),
508 weak_factory.GetWeakPtr());
509 OnceClosure non_void_weak_const_method_cb =
510 BindOnce(IgnoreResult(&NoRef::IntConstMethod0),
511 weak_factory.GetWeakPtr());
[email protected]b38d3572011-02-15 01:27:38512
tzikb9499fd92016-10-12 04:55:02513 weak_factory.InvalidateWeakPtrs();
514 std::move(non_void_weak_const_method_cb).Run();
515 std::move(non_void_weak_method_cb).Run();
[email protected]c18b1052011-03-24 02:02:17516}
517
[email protected]b38d3572011-02-15 01:27:38518// Functions that take reference parameters.
519// - Forced reference parameter type still stores a copy.
520// - Forced const reference parameter type still stores a copy.
tzikb9499fd92016-10-12 04:55:02521TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
[email protected]b38d3572011-02-15 01:27:38522 int n = 1;
523 int& ref_n = n;
524 const int& const_ref_n = n;
525
tzikb9499fd92016-10-12 04:55:02526 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
[email protected]b38d3572011-02-15 01:27:38527 EXPECT_EQ(n, ref_copies_cb.Run());
528 n++;
529 EXPECT_EQ(n - 1, ref_copies_cb.Run());
530
tzikb9499fd92016-10-12 04:55:02531 RepeatingCallback<int()> const_ref_copies_cb =
532 BindRepeating(&Identity, const_ref_n);
[email protected]b38d3572011-02-15 01:27:38533 EXPECT_EQ(n, const_ref_copies_cb.Run());
534 n++;
535 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
536}
537
tzikb9499fd92016-10-12 04:55:02538TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
539 int n = 1;
540 int& ref_n = n;
541 const int& const_ref_n = n;
542
543 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
544 n++;
545 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
546
547 OnceCallback<int()> const_ref_copies_cb =
548 BindOnce(&Identity, const_ref_n);
549 n++;
550 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
551}
552
[email protected]b38d3572011-02-15 01:27:38553// Check that we can pass in arrays and have them be stored as a pointer.
554// - Array of values stores a pointer.
555// - Array of const values stores a pointer.
tzikb9499fd92016-10-12 04:55:02556TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
[email protected]b38d3572011-02-15 01:27:38557 int array[4] = {1, 1, 1, 1};
558 const int (*const_array_ptr)[4] = &array;
559
tzikb9499fd92016-10-12 04:55:02560 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
[email protected]b38d3572011-02-15 01:27:38561 EXPECT_EQ(1, array_cb.Run());
562
tzikb9499fd92016-10-12 04:55:02563 RepeatingCallback<int()> const_array_cb =
564 BindRepeating(&ArrayGet, *const_array_ptr, 1);
[email protected]b38d3572011-02-15 01:27:38565 EXPECT_EQ(1, const_array_cb.Run());
566
567 array[1] = 3;
568 EXPECT_EQ(3, array_cb.Run());
569 EXPECT_EQ(3, const_array_cb.Run());
570}
571
tzikb9499fd92016-10-12 04:55:02572TEST_F(BindTest, ArrayArgumentBindingForOnce) {
573 int array[4] = {1, 1, 1, 1};
574 const int (*const_array_ptr)[4] = &array;
[email protected]b38d3572011-02-15 01:27:38575
tzikb9499fd92016-10-12 04:55:02576 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
577 OnceCallback<int()> const_array_cb =
578 BindOnce(&ArrayGet, *const_array_ptr, 1);
[email protected]b38d3572011-02-15 01:27:38579
tzikb9499fd92016-10-12 04:55:02580 array[1] = 3;
581 EXPECT_EQ(3, std::move(array_cb).Run());
582 EXPECT_EQ(3, std::move(const_array_cb).Run());
[email protected]b38d3572011-02-15 01:27:38583}
584
[email protected]93540582011-05-16 22:35:14585// WeakPtr() support.
586// - Method bound to WeakPtr<> to non-const object.
587// - Const method bound to WeakPtr<> to non-const object.
588// - Const method bound to WeakPtr<> to const object.
589// - Normal Function with WeakPtr<> as P1 can have return type and is
590// not canceled.
tzikb9499fd92016-10-12 04:55:02591TEST_F(BindTest, WeakPtrForRepeating) {
[email protected]93540582011-05-16 22:35:14592 EXPECT_CALL(no_ref_, VoidMethod0());
593 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
594
595 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
596 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
597
tzikb9499fd92016-10-12 04:55:02598 RepeatingClosure method_cb =
599 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14600 method_cb.Run();
601
tzikb9499fd92016-10-12 04:55:02602 RepeatingClosure const_method_cb =
603 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14604 const_method_cb.Run();
605
tzikb9499fd92016-10-12 04:55:02606 RepeatingClosure const_method_const_ptr_cb =
607 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14608 const_method_const_ptr_cb.Run();
609
tzikb9499fd92016-10-12 04:55:02610 RepeatingCallback<int(int)> normal_func_cb =
611 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14612 EXPECT_EQ(1, normal_func_cb.Run(1));
613
614 weak_factory.InvalidateWeakPtrs();
615 const_weak_factory.InvalidateWeakPtrs();
616
617 method_cb.Run();
618 const_method_cb.Run();
619 const_method_const_ptr_cb.Run();
620
621 // Still runs even after the pointers are invalidated.
622 EXPECT_EQ(2, normal_func_cb.Run(2));
623}
624
tzikb9499fd92016-10-12 04:55:02625TEST_F(BindTest, WeakPtrForOnce) {
626 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
627 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
628
629 OnceClosure method_cb =
630 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
631 OnceClosure const_method_cb =
632 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
633 OnceClosure const_method_const_ptr_cb =
634 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
635 Callback<int(int)> normal_func_cb =
636 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
637
638 weak_factory.InvalidateWeakPtrs();
639 const_weak_factory.InvalidateWeakPtrs();
640
641 std::move(method_cb).Run();
642 std::move(const_method_cb).Run();
643 std::move(const_method_const_ptr_cb).Run();
644
645 // Still runs even after the pointers are invalidated.
646 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
647}
648
[email protected]b38d3572011-02-15 01:27:38649// ConstRef() wrapper support.
650// - Binding w/o ConstRef takes a copy.
651// - Binding a ConstRef takes a reference.
652// - Binding ConstRef to a function ConstRef does not copy on invoke.
tzikb9499fd92016-10-12 04:55:02653TEST_F(BindTest, ConstRefForRepeating) {
[email protected]b38d3572011-02-15 01:27:38654 int n = 1;
655
tzikb9499fd92016-10-12 04:55:02656 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
657 RepeatingCallback<int()> const_ref_cb = BindRepeating(&Identity, ConstRef(n));
[email protected]b38d3572011-02-15 01:27:38658 EXPECT_EQ(n, copy_cb.Run());
659 EXPECT_EQ(n, const_ref_cb.Run());
660 n++;
661 EXPECT_EQ(n - 1, copy_cb.Run());
662 EXPECT_EQ(n, const_ref_cb.Run());
663
664 int copies = 0;
665 int assigns = 0;
tzik52dcd672016-02-15 11:54:30666 int move_constructs = 0;
667 int move_assigns = 0;
668 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
tzikb9499fd92016-10-12 04:55:02669 RepeatingCallback<int()> all_const_ref_cb =
670 BindRepeating(&GetCopies, ConstRef(counter));
[email protected]b38d3572011-02-15 01:27:38671 EXPECT_EQ(0, all_const_ref_cb.Run());
672 EXPECT_EQ(0, copies);
673 EXPECT_EQ(0, assigns);
tzik52dcd672016-02-15 11:54:30674 EXPECT_EQ(0, move_constructs);
675 EXPECT_EQ(0, move_assigns);
[email protected]b38d3572011-02-15 01:27:38676}
677
tzikb9499fd92016-10-12 04:55:02678TEST_F(BindTest, ConstRefForOnce) {
679 int n = 1;
[email protected]edd2f1b2013-06-22 20:32:50680
tzikb9499fd92016-10-12 04:55:02681 OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
682 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, ConstRef(n));
683 n++;
684 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
685 EXPECT_EQ(n, std::move(const_ref_cb).Run());
686
687 int copies = 0;
688 int assigns = 0;
689 int move_constructs = 0;
690 int move_assigns = 0;
691 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
692 OnceCallback<int()> all_const_ref_cb =
693 BindOnce(&GetCopies, ConstRef(counter));
694 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
695 EXPECT_EQ(0, copies);
696 EXPECT_EQ(0, assigns);
697 EXPECT_EQ(0, move_constructs);
698 EXPECT_EQ(0, move_assigns);
[email protected]edd2f1b2013-06-22 20:32:50699}
700
[email protected]08aa4552011-10-15 00:34:42701// Test Owned() support.
tzikb9499fd92016-10-12 04:55:02702TEST_F(BindTest, OwnedForRepeating) {
[email protected]08aa4552011-10-15 00:34:42703 int deletes = 0;
704 DeleteCounter* counter = new DeleteCounter(&deletes);
705
706 // If we don't capture, delete happens on Callback destruction/reset.
707 // return the same value.
tzikb9499fd92016-10-12 04:55:02708 RepeatingCallback<DeleteCounter*()> no_capture_cb =
709 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
[email protected]206a2ae82011-12-22 21:12:58710 ASSERT_EQ(counter, no_capture_cb.Run());
711 ASSERT_EQ(counter, no_capture_cb.Run());
[email protected]08aa4552011-10-15 00:34:42712 EXPECT_EQ(0, deletes);
713 no_capture_cb.Reset(); // This should trigger a delete.
714 EXPECT_EQ(1, deletes);
715
716 deletes = 0;
717 counter = new DeleteCounter(&deletes);
tzikb9499fd92016-10-12 04:55:02718 RepeatingClosure own_object_cb =
719 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
[email protected]08aa4552011-10-15 00:34:42720 own_object_cb.Run();
721 EXPECT_EQ(0, deletes);
722 own_object_cb.Reset();
723 EXPECT_EQ(1, deletes);
724}
725
tzikb9499fd92016-10-12 04:55:02726TEST_F(BindTest, OwnedForOnce) {
727 int deletes = 0;
728 DeleteCounter* counter = new DeleteCounter(&deletes);
729
730 // If we don't capture, delete happens on Callback destruction/reset.
731 // return the same value.
732 OnceCallback<DeleteCounter*()> no_capture_cb =
733 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
734 EXPECT_EQ(0, deletes);
735 no_capture_cb.Reset(); // This should trigger a delete.
736 EXPECT_EQ(1, deletes);
737
738 deletes = 0;
739 counter = new DeleteCounter(&deletes);
740 OnceClosure own_object_cb =
741 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
742 EXPECT_EQ(0, deletes);
743 own_object_cb.Reset();
744 EXPECT_EQ(1, deletes);
745}
746
747template <typename T>
748class BindVariantsTest : public ::testing::Test {
749};
750
751struct RepeatingTestConfig {
752 template <typename Signature>
753 using CallbackType = RepeatingCallback<Signature>;
754 using ClosureType = RepeatingClosure;
755
756 template <typename F, typename... Args>
757 static CallbackType<MakeUnboundRunType<F, Args...>>
758 Bind(F&& f, Args&&... args) {
759 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
760 }
761};
762
763struct OnceTestConfig {
764 template <typename Signature>
765 using CallbackType = OnceCallback<Signature>;
766 using ClosureType = OnceClosure;
767
768 template <typename F, typename... Args>
769 static CallbackType<MakeUnboundRunType<F, Args...>>
770 Bind(F&& f, Args&&... args) {
771 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
772 }
773};
774
775using BindVariantsTestConfig = ::testing::Types<
776 RepeatingTestConfig, OnceTestConfig>;
777TYPED_TEST_CASE(BindVariantsTest, BindVariantsTestConfig);
778
779template <typename TypeParam, typename Signature>
780using CallbackType = typename TypeParam::template CallbackType<Signature>;
781
782// Function type support.
783// - Normal function.
784// - Normal function bound with non-refcounted first argument.
785// - Method bound to non-const object.
786// - Method bound to scoped_refptr.
787// - Const method bound to non-const object.
788// - Const method bound to const object.
789// - Derived classes can be used with pointers to non-virtual base functions.
790// - Derived classes can be used with pointers to virtual base functions (and
791// preserve virtual dispatch).
792TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
793 using ClosureType = typename TypeParam::ClosureType;
794
795 StrictMock<HasRef> has_ref;
796 StrictMock<NoRef> no_ref;
797 StrictMock<NoRef> static_func_mock;
798 const HasRef* const_has_ref_ptr = &has_ref;
799 g_func_mock_ptr = &static_func_mock;
800
801 EXPECT_CALL(static_func_mock, VoidMethod0());
802 EXPECT_CALL(has_ref, AddRef()).Times(4);
803 EXPECT_CALL(has_ref, Release()).Times(4);
804 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
805 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
806
807 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
808 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
809 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
810 std::move(normal_cb).Run();
811 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
812
813 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
814 ClosureType method_refptr_cb = TypeParam::Bind(&HasRef::VoidMethod0,
815 make_scoped_refptr(&has_ref));
816 ClosureType const_method_nonconst_obj_cb =
817 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
818 ClosureType const_method_const_obj_cb =
819 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
820 std::move(method_cb).Run();
821 std::move(method_refptr_cb).Run();
822 std::move(const_method_nonconst_obj_cb).Run();
823 std::move(const_method_const_obj_cb).Run();
824
825 Child child;
826 child.value = 0;
827 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
828 std::move(virtual_set_cb).Run();
829 EXPECT_EQ(kChildValue, child.value);
830
831 child.value = 0;
832 ClosureType non_virtual_set_cb =
833 TypeParam::Bind(&Parent::NonVirtualSet, &child);
834 std::move(non_virtual_set_cb).Run();
835 EXPECT_EQ(kParentValue, child.value);
836}
837
838// Return value support.
839// - Function with return value.
840// - Method with return value.
841// - Const method with return value.
842// - Move-only return value.
843TYPED_TEST(BindVariantsTest, ReturnValues) {
844 StrictMock<NoRef> static_func_mock;
845 StrictMock<HasRef> has_ref;
846 g_func_mock_ptr = &static_func_mock;
847 const HasRef* const_has_ref_ptr = &has_ref;
848
849 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
850 EXPECT_CALL(has_ref, AddRef()).Times(4);
851 EXPECT_CALL(has_ref, Release()).Times(4);
852 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
853 EXPECT_CALL(has_ref, IntConstMethod0())
854 .WillOnce(Return(41337))
855 .WillOnce(Return(51337));
856 EXPECT_CALL(has_ref, UniquePtrMethod0())
857 .WillOnce(Return(ByMove(MakeUnique<int>(42))));
858
859 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
860 CallbackType<TypeParam, int()> method_cb =
861 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
862 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
863 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
864 CallbackType<TypeParam, int()> const_method_const_obj_cb =
865 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
866 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
867 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
868 EXPECT_EQ(1337, std::move(normal_cb).Run());
869 EXPECT_EQ(31337, std::move(method_cb).Run());
870 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
871 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
872 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
873}
874
875// Argument binding tests.
876// - Argument binding to primitive.
877// - Argument binding to primitive pointer.
878// - Argument binding to a literal integer.
879// - Argument binding to a literal string.
880// - Argument binding with template function.
881// - Argument binding to an object.
882// - Argument binding to pointer to incomplete type.
883// - Argument gets type converted.
884// - Pointer argument gets converted.
885// - Const Reference forces conversion.
886TYPED_TEST(BindVariantsTest, ArgumentBinding) {
887 int n = 2;
888
889 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
890 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
891 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
892 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
893 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
894
895 NoRefParent p;
896 p.value = 5;
897 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
898
899 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
900 EXPECT_EQ(incomplete_ptr,
901 TypeParam::Bind(&PolymorphicIdentity<IncompleteType*>,
902 incomplete_ptr).Run());
903
904 NoRefChild c;
905 c.value = 6;
906 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
907
908 c.value = 7;
909 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
910
911 c.value = 8;
912 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
913}
914
915// Unbound argument type support tests.
916// - Unbound value.
917// - Unbound pointer.
918// - Unbound reference.
919// - Unbound const reference.
920// - Unbound unsized array.
921// - Unbound sized array.
922// - Unbound array-of-arrays.
923TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
924 CallbackType<TypeParam, void(int)> unbound_value_cb =
925 TypeParam::Bind(&VoidPolymorphic<int>::Run);
926 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
927 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
928 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
929 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
930 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
931 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
932 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
933 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
934 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
935 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
936 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
937 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
938 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
939 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
940}
941
942// Function with unbound reference parameter.
943// - Original parameter is modified by callback.
944TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
945 int n = 0;
946 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
947 TypeParam::Bind(&RefArgSet);
948 std::move(unbound_ref_cb).Run(n);
949 EXPECT_EQ(2, n);
950}
951
952// Unretained() wrapper support.
953// - Method bound to Unretained() non-const object.
954// - Const method bound to Unretained() non-const object.
955// - Const method bound to Unretained() const object.
956TYPED_TEST(BindVariantsTest, Unretained) {
957 StrictMock<NoRef> no_ref;
958 const NoRef* const_no_ref_ptr = &no_ref;
959
960 EXPECT_CALL(no_ref, VoidMethod0());
961 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
962
963 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
964 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
965 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
966}
967
968TYPED_TEST(BindVariantsTest, ScopedRefptr) {
969 StrictMock<HasRef> has_ref;
970 EXPECT_CALL(has_ref, AddRef()).Times(1);
971 EXPECT_CALL(has_ref, Release()).Times(1);
972
973 const scoped_refptr<HasRef> refptr(&has_ref);
974 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb =
975 TypeParam::Bind(&FunctionWithScopedRefptrFirstParam,
976 base::ConstRef(refptr), 1);
977 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
978}
979
980TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
tzik4435e8042016-05-11 23:05:05981 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
982 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
tzikb9499fd92016-10-12 04:55:02983 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
tzik4435e8042016-05-11 23:05:05984}
985
dchengf10b7732016-01-21 19:37:55986// Tests for Passed() wrapper support:
[email protected]206a2ae82011-12-22 21:12:58987// - Passed() can be constructed from a pointer to scoper.
988// - Passed() can be constructed from a scoper rvalue.
989// - Using Passed() gives Callback Ownership.
990// - Ownership is transferred from Callback to callee on the first Run().
991// - Callback supports unbound arguments.
dchengf10b7732016-01-21 19:37:55992template <typename T>
993class BindMoveOnlyTypeTest : public ::testing::Test {
994};
995
996struct CustomDeleter {
997 void operator()(DeleteCounter* c) { delete c; }
998};
999
1000using MoveOnlyTypesToTest =
dcheng093de9b2016-04-04 21:25:511001 ::testing::Types<std::unique_ptr<DeleteCounter>,
dchengf10b7732016-01-21 19:37:551002 std::unique_ptr<DeleteCounter, CustomDeleter>>;
1003TYPED_TEST_CASE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
1004
1005TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
[email protected]206a2ae82011-12-22 21:12:581006 int deletes = 0;
1007
dchengf10b7732016-01-21 19:37:551008 TypeParam ptr(new DeleteCounter(&deletes));
1009 Callback<TypeParam()> callback = Bind(&PassThru<TypeParam>, Passed(&ptr));
[email protected]206a2ae82011-12-22 21:12:581010 EXPECT_FALSE(ptr.get());
1011 EXPECT_EQ(0, deletes);
1012
1013 // If we never invoke the Callback, it retains ownership and deletes.
[email protected]206a2ae82011-12-22 21:12:581014 callback.Reset();
[email protected]206a2ae82011-12-22 21:12:581015 EXPECT_EQ(1, deletes);
[email protected]206a2ae82011-12-22 21:12:581016}
1017
dchengf10b7732016-01-21 19:37:551018TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
dcheng69f2a042015-12-14 20:31:521019 int deletes = 0;
dchengf10b7732016-01-21 19:37:551020 Callback<TypeParam()> callback = Bind(
1021 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
dcheng69f2a042015-12-14 20:31:521022 EXPECT_EQ(0, deletes);
1023
1024 // If we never invoke the Callback, it retains ownership and deletes.
dchengf10b7732016-01-21 19:37:551025 callback.Reset();
dcheng69f2a042015-12-14 20:31:521026 EXPECT_EQ(1, deletes);
dchengf10b7732016-01-21 19:37:551027}
dcheng69f2a042015-12-14 20:31:521028
dchengf10b7732016-01-21 19:37:551029// Check that ownership can be transferred back out.
1030TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
1031 int deletes = 0;
dcheng69f2a042015-12-14 20:31:521032 DeleteCounter* counter = new DeleteCounter(&deletes);
dchengf10b7732016-01-21 19:37:551033 Callback<TypeParam()> callback =
1034 Bind(&PassThru<TypeParam>, Passed(TypeParam(counter)));
1035 TypeParam result = callback.Run();
dcheng69f2a042015-12-14 20:31:521036 ASSERT_EQ(counter, result.get());
1037 EXPECT_EQ(0, deletes);
1038
1039 // Resetting does not delete since ownership was transferred.
1040 callback.Reset();
1041 EXPECT_EQ(0, deletes);
1042
1043 // Ensure that we actually did get ownership.
1044 result.reset();
1045 EXPECT_EQ(1, deletes);
dchengf10b7732016-01-21 19:37:551046}
dcheng69f2a042015-12-14 20:31:521047
dchengf10b7732016-01-21 19:37:551048TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
1049 int deletes = 0;
1050 TypeParam ptr(new DeleteCounter(&deletes));
dcheng69f2a042015-12-14 20:31:521051 // Test unbound argument forwarding.
dchengf10b7732016-01-21 19:37:551052 Callback<TypeParam(TypeParam)> cb_unbound = Bind(&PassThru<TypeParam>);
dcheng69f2a042015-12-14 20:31:521053 cb_unbound.Run(std::move(ptr));
dchengf10b7732016-01-21 19:37:551054 EXPECT_EQ(1, deletes);
dcheng69f2a042015-12-14 20:31:521055}
1056
dcheng093de9b2016-04-04 21:25:511057void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
dcheng53b4cea2016-02-02 04:09:331058 ASSERT_EQ(1u, v.size());
1059 EXPECT_EQ(12345, *v[0]);
1060}
1061
dcheng093de9b2016-04-04 21:25:511062std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
1063 std::vector<std::unique_ptr<int>> v) {
dcheng53b4cea2016-02-02 04:09:331064 VerifyVector(v);
1065 return v;
1066}
1067
1068// Test that a vector containing move-only types can be used with Callback.
1069TEST_F(BindTest, BindMoveOnlyVector) {
dcheng093de9b2016-04-04 21:25:511070 using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
dcheng53b4cea2016-02-02 04:09:331071
1072 MoveOnlyVector v;
dcheng093de9b2016-04-04 21:25:511073 v.push_back(WrapUnique(new int(12345)));
dcheng53b4cea2016-02-02 04:09:331074
1075 // Early binding should work:
1076 base::Callback<MoveOnlyVector()> bound_cb =
1077 base::Bind(&AcceptAndReturnMoveOnlyVector, Passed(&v));
1078 MoveOnlyVector intermediate_result = bound_cb.Run();
1079 VerifyVector(intermediate_result);
1080
1081 // As should passing it as an argument to Run():
1082 base::Callback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
1083 base::Bind(&AcceptAndReturnMoveOnlyVector);
1084 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
1085 VerifyVector(final_result);
1086}
1087
tzik52dcd672016-02-15 11:54:301088// Argument copy-constructor usage for non-reference copy-only parameters.
[email protected]b38d3572011-02-15 01:27:381089// - Bound arguments are only copied once.
1090// - Forwarded arguments are only copied once.
[email protected]206a2ae82011-12-22 21:12:581091// - Forwarded arguments with coercions are only copied twice (once for the
1092// coercion, and one for the final dispatch).
[email protected]b38d3572011-02-15 01:27:381093TEST_F(BindTest, ArgumentCopies) {
1094 int copies = 0;
1095 int assigns = 0;
1096
1097 CopyCounter counter(&copies, &assigns);
tzik52dcd672016-02-15 11:54:301098 Bind(&VoidPolymorphic<CopyCounter>::Run, counter);
1099 EXPECT_EQ(1, copies);
[email protected]b38d3572011-02-15 01:27:381100 EXPECT_EQ(0, assigns);
1101
1102 copies = 0;
1103 assigns = 0;
tzik52dcd672016-02-15 11:54:301104 Bind(&VoidPolymorphic<CopyCounter>::Run, CopyCounter(&copies, &assigns));
1105 EXPECT_EQ(1, copies);
[email protected]b38d3572011-02-15 01:27:381106 EXPECT_EQ(0, assigns);
1107
1108 copies = 0;
1109 assigns = 0;
tzik52dcd672016-02-15 11:54:301110 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
tzika43eff02016-03-09 05:46:051111 EXPECT_EQ(2, copies);
[email protected]b38d3572011-02-15 01:27:381112 EXPECT_EQ(0, assigns);
tzik52dcd672016-02-15 11:54:301113
1114 copies = 0;
1115 assigns = 0;
1116 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(&copies, &assigns));
1117 EXPECT_EQ(1, copies);
1118 EXPECT_EQ(0, assigns);
1119
1120 copies = 0;
1121 assigns = 0;
1122 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
1123 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
1124 EXPECT_EQ(2, copies);
1125 EXPECT_EQ(0, assigns);
1126
1127 copies = 0;
1128 assigns = 0;
1129 Bind(&VoidPolymorphic<CopyCounter>::Run)
1130 .Run(CopyCounter(
1131 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
1132 EXPECT_EQ(2, copies);
1133 EXPECT_EQ(0, assigns);
1134}
1135
1136// Argument move-constructor usage for move-only parameters.
1137// - Bound arguments passed by move are not copied.
1138TEST_F(BindTest, ArgumentMoves) {
1139 int move_constructs = 0;
1140 int move_assigns = 0;
1141
1142 Bind(&VoidPolymorphic<const MoveCounter&>::Run,
1143 MoveCounter(&move_constructs, &move_assigns));
1144 EXPECT_EQ(1, move_constructs);
1145 EXPECT_EQ(0, move_assigns);
1146
1147 // TODO(tzik): Support binding move-only type into a non-reference parameter
1148 // of a variant of Callback.
1149
tzika43eff02016-03-09 05:46:051150 move_constructs = 0;
1151 move_assigns = 0;
1152 Bind(&VoidPolymorphic<MoveCounter>::Run)
1153 .Run(MoveCounter(&move_constructs, &move_assigns));
1154 EXPECT_EQ(1, move_constructs);
1155 EXPECT_EQ(0, move_assigns);
1156
1157 move_constructs = 0;
1158 move_assigns = 0;
1159 Bind(&VoidPolymorphic<MoveCounter>::Run)
1160 .Run(MoveCounter(DerivedCopyMoveCounter(
1161 nullptr, nullptr, &move_constructs, &move_assigns)));
1162 EXPECT_EQ(2, move_constructs);
1163 EXPECT_EQ(0, move_assigns);
tzik52dcd672016-02-15 11:54:301164}
1165
1166// Argument constructor usage for non-reference movable-copyable
1167// parameters.
1168// - Bound arguments passed by move are not copied.
1169// - Forwarded arguments are only copied once.
1170// - Forwarded arguments with coercions are only copied once and moved once.
1171TEST_F(BindTest, ArgumentCopiesAndMoves) {
1172 int copies = 0;
1173 int assigns = 0;
1174 int move_constructs = 0;
1175 int move_assigns = 0;
1176
1177 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
1178 Bind(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
1179 EXPECT_EQ(1, copies);
1180 EXPECT_EQ(0, assigns);
1181 EXPECT_EQ(0, move_constructs);
1182 EXPECT_EQ(0, move_assigns);
1183
1184 copies = 0;
1185 assigns = 0;
1186 move_constructs = 0;
1187 move_assigns = 0;
1188 Bind(&VoidPolymorphic<CopyMoveCounter>::Run,
1189 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1190 EXPECT_EQ(0, copies);
1191 EXPECT_EQ(0, assigns);
1192 EXPECT_EQ(1, move_constructs);
1193 EXPECT_EQ(0, move_assigns);
1194
1195 copies = 0;
1196 assigns = 0;
1197 move_constructs = 0;
1198 move_assigns = 0;
1199 Bind(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter);
1200 EXPECT_EQ(1, copies);
1201 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051202 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301203 EXPECT_EQ(0, move_assigns);
1204
tzik52dcd672016-02-15 11:54:301205 copies = 0;
1206 assigns = 0;
1207 move_constructs = 0;
1208 move_assigns = 0;
1209 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1210 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
tzika43eff02016-03-09 05:46:051211 EXPECT_EQ(0, copies);
tzik52dcd672016-02-15 11:54:301212 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051213 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301214 EXPECT_EQ(0, move_assigns);
1215
tzik52dcd672016-02-15 11:54:301216 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1217 &move_assigns);
1218 copies = 0;
1219 assigns = 0;
1220 move_constructs = 0;
1221 move_assigns = 0;
1222 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1223 .Run(CopyMoveCounter(derived_counter));
tzika43eff02016-03-09 05:46:051224 EXPECT_EQ(1, copies);
tzik52dcd672016-02-15 11:54:301225 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051226 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301227 EXPECT_EQ(0, move_assigns);
1228
tzik52dcd672016-02-15 11:54:301229 copies = 0;
1230 assigns = 0;
1231 move_constructs = 0;
1232 move_assigns = 0;
1233 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1234 .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1235 &copies, &assigns, &move_constructs, &move_assigns)));
tzika43eff02016-03-09 05:46:051236 EXPECT_EQ(0, copies);
tzik52dcd672016-02-15 11:54:301237 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051238 EXPECT_EQ(2, move_constructs);
tzik52dcd672016-02-15 11:54:301239 EXPECT_EQ(0, move_assigns);
[email protected]b38d3572011-02-15 01:27:381240}
1241
tzikc1db72652016-07-08 09:42:381242TEST_F(BindTest, CapturelessLambda) {
1243 EXPECT_FALSE(internal::IsConvertibleToRunType<void>::value);
1244 EXPECT_FALSE(internal::IsConvertibleToRunType<int>::value);
1245 EXPECT_FALSE(internal::IsConvertibleToRunType<void(*)()>::value);
1246 EXPECT_FALSE(internal::IsConvertibleToRunType<void(NoRef::*)()>::value);
1247
1248 auto f = []() {};
1249 EXPECT_TRUE(internal::IsConvertibleToRunType<decltype(f)>::value);
1250
1251 int i = 0;
1252 auto g = [i]() {};
1253 EXPECT_FALSE(internal::IsConvertibleToRunType<decltype(g)>::value);
1254
1255 auto h = [](int, double) { return 'k'; };
1256 EXPECT_TRUE((std::is_same<
1257 char(int, double),
1258 internal::ExtractCallableRunType<decltype(h)>>::value));
1259
1260 EXPECT_EQ(42, Bind([] { return 42; }).Run());
1261 EXPECT_EQ(42, Bind([](int i) { return i * 7; }, 6).Run());
1262
1263 int x = 1;
1264 base::Callback<void(int)> cb =
1265 Bind([](int* x, int i) { *x *= i; }, Unretained(&x));
1266 cb.Run(6);
1267 EXPECT_EQ(6, x);
1268 cb.Run(7);
1269 EXPECT_EQ(42, x);
1270}
1271
tzik59aa6bb12016-09-08 10:58:531272TEST_F(BindTest, Cancellation) {
dcheng172b6ad2016-09-24 05:05:571273 EXPECT_CALL(no_ref_, VoidMethodWithIntArg(_)).Times(2);
tzik59aa6bb12016-09-08 10:58:531274
1275 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
tzik44adf072016-10-07 04:34:541276 RepeatingCallback<void(int)> cb =
1277 BindRepeating(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1278 RepeatingClosure cb2 = BindRepeating(cb, 8);
1279 OnceClosure cb3 = BindOnce(cb, 8);
1280
1281 OnceCallback<void(int)> cb4 =
1282 BindOnce(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1283 EXPECT_FALSE(cb4.IsCancelled());
1284
1285 OnceClosure cb5 = BindOnce(std::move(cb4), 8);
tzik59aa6bb12016-09-08 10:58:531286
1287 EXPECT_FALSE(cb.IsCancelled());
1288 EXPECT_FALSE(cb2.IsCancelled());
tzik44adf072016-10-07 04:34:541289 EXPECT_FALSE(cb3.IsCancelled());
1290 EXPECT_FALSE(cb5.IsCancelled());
tzik59aa6bb12016-09-08 10:58:531291
dcheng172b6ad2016-09-24 05:05:571292 cb.Run(6);
tzik59aa6bb12016-09-08 10:58:531293 cb2.Run();
1294
1295 weak_factory.InvalidateWeakPtrs();
1296
1297 EXPECT_TRUE(cb.IsCancelled());
1298 EXPECT_TRUE(cb2.IsCancelled());
tzik44adf072016-10-07 04:34:541299 EXPECT_TRUE(cb3.IsCancelled());
1300 EXPECT_TRUE(cb5.IsCancelled());
tzik59aa6bb12016-09-08 10:58:531301
dcheng172b6ad2016-09-24 05:05:571302 cb.Run(6);
tzik59aa6bb12016-09-08 10:58:531303 cb2.Run();
tzik44adf072016-10-07 04:34:541304 std::move(cb3).Run();
1305 std::move(cb5).Run();
tzik59aa6bb12016-09-08 10:58:531306}
1307
tzik27d1e312016-09-13 05:28:591308TEST_F(BindTest, OnceCallback) {
tzik27d1e312016-09-13 05:28:591309 // Check if Callback variants have declarations of conversions as expected.
1310 // Copy constructor and assignment of RepeatingCallback.
1311 static_assert(std::is_constructible<
1312 RepeatingClosure, const RepeatingClosure&>::value,
1313 "RepeatingClosure should be copyable.");
1314 static_assert(is_assignable<
1315 RepeatingClosure, const RepeatingClosure&>::value,
1316 "RepeatingClosure should be copy-assignable.");
1317
1318 // Move constructor and assignment of RepeatingCallback.
1319 static_assert(std::is_constructible<
1320 RepeatingClosure, RepeatingClosure&&>::value,
1321 "RepeatingClosure should be movable.");
1322 static_assert(is_assignable<
1323 RepeatingClosure, RepeatingClosure&&>::value,
1324 "RepeatingClosure should be move-assignable");
1325
1326 // Conversions from OnceCallback to RepeatingCallback.
1327 static_assert(!std::is_constructible<
1328 RepeatingClosure, const OnceClosure&>::value,
1329 "OnceClosure should not be convertible to RepeatingClosure.");
1330 static_assert(!is_assignable<
1331 RepeatingClosure, const OnceClosure&>::value,
1332 "OnceClosure should not be convertible to RepeatingClosure.");
1333
1334 // Destructive conversions from OnceCallback to RepeatingCallback.
1335 static_assert(!std::is_constructible<
1336 RepeatingClosure, OnceClosure&&>::value,
1337 "OnceClosure should not be convertible to RepeatingClosure.");
1338 static_assert(!is_assignable<
1339 RepeatingClosure, OnceClosure&&>::value,
1340 "OnceClosure should not be convertible to RepeatingClosure.");
1341
1342 // Copy constructor and assignment of OnceCallback.
1343 static_assert(!std::is_constructible<
1344 OnceClosure, const OnceClosure&>::value,
1345 "OnceClosure should not be copyable.");
1346 static_assert(!is_assignable<
1347 OnceClosure, const OnceClosure&>::value,
1348 "OnceClosure should not be copy-assignable");
1349
1350 // Move constructor and assignment of OnceCallback.
1351 static_assert(std::is_constructible<
1352 OnceClosure, OnceClosure&&>::value,
1353 "OnceClosure should be movable.");
1354 static_assert(is_assignable<
1355 OnceClosure, OnceClosure&&>::value,
1356 "OnceClosure should be move-assignable.");
1357
1358 // Conversions from RepeatingCallback to OnceCallback.
1359 static_assert(std::is_constructible<
1360 OnceClosure, const RepeatingClosure&>::value,
1361 "RepeatingClosure should be convertible to OnceClosure.");
1362 static_assert(is_assignable<
1363 OnceClosure, const RepeatingClosure&>::value,
1364 "RepeatingClosure should be convertible to OnceClosure.");
1365
1366 // Destructive conversions from RepeatingCallback to OnceCallback.
1367 static_assert(std::is_constructible<
1368 OnceClosure, RepeatingClosure&&>::value,
1369 "RepeatingClosure should be convertible to OnceClosure.");
1370 static_assert(is_assignable<
1371 OnceClosure, RepeatingClosure&&>::value,
1372 "RepeatingClosure should be covretible to OnceClosure.");
1373
1374 OnceClosure cb = BindOnce(&VoidPolymorphic<>::Run);
1375 std::move(cb).Run();
1376
1377 // RepeatingCallback should be convertible to OnceCallback.
1378 OnceClosure cb2 = BindRepeating(&VoidPolymorphic<>::Run);
1379 std::move(cb2).Run();
1380
1381 RepeatingClosure cb3 = BindRepeating(&VoidPolymorphic<>::Run);
1382 cb = cb3;
1383 std::move(cb).Run();
1384
1385 cb = std::move(cb2);
1386
1387 OnceCallback<void(int)> cb4 = BindOnce(
1388 &VoidPolymorphic<std::unique_ptr<int>, int>::Run, MakeUnique<int>(0));
1389 BindOnce(std::move(cb4), 1).Run();
1390}
1391
[email protected]b38d3572011-02-15 01:27:381392// Callback construction and assignment tests.
1393// - Construction from an InvokerStorageHolder should not cause ref/deref.
1394// - Assignment from other callback should only cause one ref
1395//
1396// TODO(ajwong): Is there actually a way to test this?
1397
[email protected]054ac7542011-02-27 01:25:591398#if defined(OS_WIN)
1399int __fastcall FastCallFunc(int n) {
1400 return n;
1401}
1402
1403int __stdcall StdCallFunc(int n) {
1404 return n;
1405}
1406
1407// Windows specific calling convention support.
1408// - Can bind a __fastcall function.
1409// - Can bind a __stdcall function.
1410TEST_F(BindTest, WindowsCallingConventions) {
tzik3bc7779b2015-12-19 09:18:461411 Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1);
[email protected]054ac7542011-02-27 01:25:591412 EXPECT_EQ(1, fastcall_cb.Run());
1413
tzik3bc7779b2015-12-19 09:18:461414 Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2);
[email protected]054ac7542011-02-27 01:25:591415 EXPECT_EQ(2, stdcall_cb.Run());
1416}
1417#endif
1418
[email protected]8cf362c2012-11-20 08:28:141419// Test null callbacks cause a DCHECK.
1420TEST(BindDeathTest, NullCallback) {
1421 base::Callback<void(int)> null_cb;
1422 ASSERT_TRUE(null_cb.is_null());
gab5e69cff2016-08-05 03:25:401423 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42));
[email protected]8cf362c2012-11-20 08:28:141424}
1425
[email protected]b38d3572011-02-15 01:27:381426} // namespace
1427} // namespace base