blob: 046f03e44da8495822661f7832aec658997659b0 [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"
tzikf98654b2017-12-02 03:28:5816#include "base/test/bind_test_util.h"
gabc964a852016-08-01 16:39:5617#include "base/test/gtest_util.h"
avi9b6f42932015-12-26 22:15:1418#include "build/build_config.h"
[email protected]b38d3572011-02-15 01:27:3819#include "testing/gmock/include/gmock/gmock.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
dcheng172b6ad2016-09-24 05:05:5722using ::testing::_;
[email protected]b38d3572011-02-15 01:27:3823using ::testing::Mock;
tzikb9499fd92016-10-12 04:55:0224using ::testing::ByMove;
[email protected]b38d3572011-02-15 01:27:3825using ::testing::Return;
26using ::testing::StrictMock;
27
28namespace base {
29namespace {
30
[email protected]8217d4542011-10-01 06:31:4131class IncompleteType;
32
[email protected]b38d3572011-02-15 01:27:3833class NoRef {
34 public:
Chris Watkinsbb7211c2017-11-29 07:16:3835 NoRef() = default;
[email protected]b38d3572011-02-15 01:27:3836
tzik3bc7779b2015-12-19 09:18:4637 MOCK_METHOD0(VoidMethod0, void());
38 MOCK_CONST_METHOD0(VoidConstMethod0, void());
[email protected]b38d3572011-02-15 01:27:3839
tzik3bc7779b2015-12-19 09:18:4640 MOCK_METHOD0(IntMethod0, int());
41 MOCK_CONST_METHOD0(IntConstMethod0, int());
[email protected]b38d3572011-02-15 01:27:3842
dcheng172b6ad2016-09-24 05:05:5743 MOCK_METHOD1(VoidMethodWithIntArg, void(int));
tzikb9499fd92016-10-12 04:55:0244 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
dcheng172b6ad2016-09-24 05:05:5745
[email protected]b38d3572011-02-15 01:27:3846 private:
47 // Particularly important in this test to ensure no copies are made.
48 DISALLOW_COPY_AND_ASSIGN(NoRef);
49};
50
51class HasRef : public NoRef {
52 public:
Chris Watkinsbb7211c2017-11-29 07:16:3853 HasRef() = default;
[email protected]b38d3572011-02-15 01:27:3854
tzik3bc7779b2015-12-19 09:18:4655 MOCK_CONST_METHOD0(AddRef, void());
56 MOCK_CONST_METHOD0(Release, bool());
[email protected]b38d3572011-02-15 01:27:3857
58 private:
59 // Particularly important in this test to ensure no copies are made.
60 DISALLOW_COPY_AND_ASSIGN(HasRef);
61};
62
[email protected]690bda882011-04-13 22:40:4663class HasRefPrivateDtor : public HasRef {
64 private:
Chris Watkinsbb7211c2017-11-29 07:16:3865 ~HasRefPrivateDtor() = default;
[email protected]690bda882011-04-13 22:40:4666};
67
[email protected]b38d3572011-02-15 01:27:3868static const int kParentValue = 1;
69static const int kChildValue = 2;
70
71class Parent {
72 public:
tzik3bc7779b2015-12-19 09:18:4673 void AddRef() const {}
74 void Release() const {}
[email protected]b38d3572011-02-15 01:27:3875 virtual void VirtualSet() { value = kParentValue; }
76 void NonVirtualSet() { value = kParentValue; }
77 int value;
78};
79
80class Child : public Parent {
81 public:
dcheng56488182014-10-21 10:54:5182 void VirtualSet() override { value = kChildValue; }
[email protected]b38d3572011-02-15 01:27:3883 void NonVirtualSet() { value = kChildValue; }
84};
85
86class NoRefParent {
87 public:
88 virtual void VirtualSet() { value = kParentValue; }
89 void NonVirtualSet() { value = kParentValue; }
90 int value;
91};
92
93class NoRefChild : public NoRefParent {
dcheng56488182014-10-21 10:54:5194 void VirtualSet() override { value = kChildValue; }
[email protected]b38d3572011-02-15 01:27:3895 void NonVirtualSet() { value = kChildValue; }
96};
97
tzik52dcd672016-02-15 11:54:3098// Used for probing the number of copies and moves that occur if a type must be
99// coerced during argument forwarding in the Run() methods.
100struct DerivedCopyMoveCounter {
101 DerivedCopyMoveCounter(int* copies,
102 int* assigns,
103 int* move_constructs,
104 int* move_assigns)
105 : copies_(copies),
106 assigns_(assigns),
107 move_constructs_(move_constructs),
108 move_assigns_(move_assigns) {}
[email protected]b38d3572011-02-15 01:27:38109 int* copies_;
110 int* assigns_;
tzik52dcd672016-02-15 11:54:30111 int* move_constructs_;
112 int* move_assigns_;
[email protected]b38d3572011-02-15 01:27:38113};
114
tzik52dcd672016-02-15 11:54:30115// Used for probing the number of copies and moves in an argument.
116class CopyMoveCounter {
[email protected]b38d3572011-02-15 01:27:38117 public:
tzik52dcd672016-02-15 11:54:30118 CopyMoveCounter(int* copies,
119 int* assigns,
120 int* move_constructs,
121 int* move_assigns)
122 : copies_(copies),
123 assigns_(assigns),
124 move_constructs_(move_constructs),
125 move_assigns_(move_assigns) {}
126
127 CopyMoveCounter(const CopyMoveCounter& other)
128 : copies_(other.copies_),
129 assigns_(other.assigns_),
130 move_constructs_(other.move_constructs_),
131 move_assigns_(other.move_assigns_) {
132 (*copies_)++;
[email protected]b38d3572011-02-15 01:27:38133 }
134
tzik52dcd672016-02-15 11:54:30135 CopyMoveCounter(CopyMoveCounter&& other)
[email protected]b38d3572011-02-15 01:27:38136 : copies_(other.copies_),
tzik52dcd672016-02-15 11:54:30137 assigns_(other.assigns_),
138 move_constructs_(other.move_constructs_),
139 move_assigns_(other.move_assigns_) {
140 (*move_constructs_)++;
[email protected]b38d3572011-02-15 01:27:38141 }
142
[email protected]206a2ae82011-12-22 21:12:58143 // Probing for copies from coercion.
tzik52dcd672016-02-15 11:54:30144 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
[email protected]b38d3572011-02-15 01:27:38145 : copies_(other.copies_),
tzik52dcd672016-02-15 11:54:30146 assigns_(other.assigns_),
147 move_constructs_(other.move_constructs_),
148 move_assigns_(other.move_assigns_) {
[email protected]b38d3572011-02-15 01:27:38149 (*copies_)++;
150 }
151
tzik52dcd672016-02-15 11:54:30152 // Probing for moves from coercion.
153 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
154 : copies_(other.copies_),
155 assigns_(other.assigns_),
156 move_constructs_(other.move_constructs_),
157 move_assigns_(other.move_assigns_) {
158 (*move_constructs_)++;
159 }
160
161 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
[email protected]b38d3572011-02-15 01:27:38162 copies_ = rhs.copies_;
163 assigns_ = rhs.assigns_;
tzik52dcd672016-02-15 11:54:30164 move_constructs_ = rhs.move_constructs_;
165 move_assigns_ = rhs.move_assigns_;
[email protected]b38d3572011-02-15 01:27:38166
tzik52dcd672016-02-15 11:54:30167 (*assigns_)++;
168
169 return *this;
170 }
171
172 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
173 copies_ = rhs.copies_;
174 assigns_ = rhs.assigns_;
175 move_constructs_ = rhs.move_constructs_;
176 move_assigns_ = rhs.move_assigns_;
177
178 (*move_assigns_)++;
[email protected]b38d3572011-02-15 01:27:38179
180 return *this;
181 }
182
183 int copies() const {
184 return *copies_;
185 }
186
[email protected]b38d3572011-02-15 01:27:38187 private:
188 int* copies_;
189 int* assigns_;
tzik52dcd672016-02-15 11:54:30190 int* move_constructs_;
191 int* move_assigns_;
192};
193
194// Used for probing the number of copies in an argument. The instance is a
195// copyable and non-movable type.
196class CopyCounter {
197 public:
198 CopyCounter(int* copies, int* assigns)
199 : counter_(copies, assigns, nullptr, nullptr) {}
Chris Watkinsbb7211c2017-11-29 07:16:38200 CopyCounter(const CopyCounter& other) = default;
201 CopyCounter& operator=(const CopyCounter& other) = default;
tzik52dcd672016-02-15 11:54:30202
203 explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {}
204
205 int copies() const { return counter_.copies(); }
206
207 private:
208 CopyMoveCounter counter_;
209};
210
211// Used for probing the number of moves in an argument. The instance is a
212// non-copyable and movable type.
213class MoveCounter {
214 public:
215 MoveCounter(int* move_constructs, int* move_assigns)
216 : counter_(nullptr, nullptr, move_constructs, move_assigns) {}
217 MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {}
218 MoveCounter& operator=(MoveCounter&& other) {
219 counter_ = std::move(other.counter_);
220 return *this;
221 }
222
223 explicit MoveCounter(DerivedCopyMoveCounter&& other)
224 : counter_(std::move(other)) {}
225
226 private:
227 CopyMoveCounter counter_;
[email protected]b38d3572011-02-15 01:27:38228};
229
[email protected]08aa4552011-10-15 00:34:42230class DeleteCounter {
231 public:
232 explicit DeleteCounter(int* deletes)
233 : deletes_(deletes) {
234 }
235
236 ~DeleteCounter() {
237 (*deletes_)++;
238 }
239
240 void VoidMethod0() {}
241
242 private:
243 int* deletes_;
244};
245
[email protected]206a2ae82011-12-22 21:12:58246template <typename T>
247T PassThru(T scoper) {
dcheng69f2a042015-12-14 20:31:52248 return scoper;
[email protected]206a2ae82011-12-22 21:12:58249}
250
[email protected]b38d3572011-02-15 01:27:38251// Some test functions that we can Bind to.
252template <typename T>
253T PolymorphicIdentity(T t) {
254 return t;
255}
256
tzik7fe3a682015-12-18 02:23:26257template <typename... Ts>
258struct VoidPolymorphic {
259 static void Run(Ts... t) {}
260};
[email protected]b38d3572011-02-15 01:27:38261
262int Identity(int n) {
263 return n;
264}
265
266int ArrayGet(const int array[], int n) {
267 return array[n];
268}
269
270int Sum(int a, int b, int c, int d, int e, int f) {
271 return a + b + c + d + e + f;
272}
273
274const char* CStringIdentity(const char* s) {
275 return s;
276}
277
tzik52dcd672016-02-15 11:54:30278int GetCopies(const CopyMoveCounter& counter) {
[email protected]b38d3572011-02-15 01:27:38279 return counter.copies();
280}
281
282int UnwrapNoRefParent(NoRefParent p) {
283 return p.value;
284}
285
286int UnwrapNoRefParentPtr(NoRefParent* p) {
287 return p->value;
288}
289
290int UnwrapNoRefParentConstRef(const NoRefParent& p) {
291 return p.value;
292}
293
[email protected]c18b1052011-03-24 02:02:17294void RefArgSet(int &n) {
295 n = 2;
296}
297
[email protected]e24f8762011-12-20 00:10:04298void PtrArgSet(int *n) {
299 *n = 2;
300}
301
[email protected]93540582011-05-16 22:35:14302int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
303 return n;
304}
305
[email protected]edd2f1b2013-06-22 20:32:50306int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
307 return n;
308}
309
[email protected]e24f8762011-12-20 00:10:04310void TakesACallback(const Closure& callback) {
311 callback.Run();
312}
313
[email protected]b38d3572011-02-15 01:27:38314class BindTest : public ::testing::Test {
315 public:
316 BindTest() {
317 const_has_ref_ptr_ = &has_ref_;
318 const_no_ref_ptr_ = &no_ref_;
319 static_func_mock_ptr = &static_func_mock_;
320 }
321
Chris Watkinsbb7211c2017-11-29 07:16:38322 virtual ~BindTest() = default;
[email protected]b38d3572011-02-15 01:27:38323
tzik3bc7779b2015-12-19 09:18:46324 static void VoidFunc0() {
[email protected]b38d3572011-02-15 01:27:38325 static_func_mock_ptr->VoidMethod0();
326 }
327
tzik3bc7779b2015-12-19 09:18:46328 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
[email protected]b38d3572011-02-15 01:27:38329
330 protected:
331 StrictMock<NoRef> no_ref_;
332 StrictMock<HasRef> has_ref_;
333 const HasRef* const_has_ref_ptr_;
334 const NoRef* const_no_ref_ptr_;
335 StrictMock<NoRef> static_func_mock_;
336
337 // Used by the static functions to perform expectations.
338 static StrictMock<NoRef>* static_func_mock_ptr;
339
340 private:
341 DISALLOW_COPY_AND_ASSIGN(BindTest);
342};
343
344StrictMock<NoRef>* BindTest::static_func_mock_ptr;
tzikb9499fd92016-10-12 04:55:02345StrictMock<NoRef>* g_func_mock_ptr;
346
347void VoidFunc0() {
348 g_func_mock_ptr->VoidMethod0();
349}
350
351int IntFunc0() {
352 return g_func_mock_ptr->IntMethod0();
353}
[email protected]b38d3572011-02-15 01:27:38354
tzik4d4da502016-08-23 04:23:49355TEST_F(BindTest, BasicTest) {
356 Callback<int(int, int, int)> cb = Bind(&Sum, 32, 16, 8);
357 EXPECT_EQ(92, cb.Run(13, 12, 11));
[email protected]b38d3572011-02-15 01:27:38358
tzik4d4da502016-08-23 04:23:49359 Callback<int(int, int, int, int, int, int)> c1 = Bind(&Sum);
360 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
[email protected]b38d3572011-02-15 01:27:38361
tzik4d4da502016-08-23 04:23:49362 Callback<int(int, int, int)> c2 = Bind(c1, 32, 16, 8);
363 EXPECT_EQ(86, c2.Run(11, 10, 9));
[email protected]b38d3572011-02-15 01:27:38364
tzik4d4da502016-08-23 04:23:49365 Callback<int()> c3 = Bind(c2, 4, 2, 1);
366 EXPECT_EQ(63, c3.Run());
[email protected]cea20fe42011-09-30 09:09:34367}
368
[email protected]e24f8762011-12-20 00:10:04369// Test that currying the rvalue result of another Bind() works correctly.
370// - rvalue should be usable as argument to Bind().
371// - multiple runs of resulting Callback remain valid.
372TEST_F(BindTest, CurryingRvalueResultOfBind) {
373 int n = 0;
tzikb9499fd92016-10-12 04:55:02374 RepeatingClosure cb = BindRepeating(&TakesACallback,
375 BindRepeating(&PtrArgSet, &n));
[email protected]e24f8762011-12-20 00:10:04376
377 // If we implement Bind() such that the return value has auto_ptr-like
378 // semantics, the second call here will fail because ownership of
379 // the internal BindState<> would have been transfered to a *temporary*
380 // constructon of a Callback object on the first call.
381 cb.Run();
382 EXPECT_EQ(2, n);
383
384 n = 0;
385 cb.Run();
386 EXPECT_EQ(2, n);
387}
388
tzikb9499fd92016-10-12 04:55:02389TEST_F(BindTest, RepeatingCallbackBasicTest) {
390 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
[email protected]b38d3572011-02-15 01:27:38391
tzikb9499fd92016-10-12 04:55:02392 // RepeatingCallback can run via a lvalue-reference.
393 EXPECT_EQ(63, c0.Run(32));
[email protected]81814bce2011-09-10 03:03:00394
tzikb9499fd92016-10-12 04:55:02395 // It is valid to call a RepeatingCallback more than once.
396 EXPECT_EQ(54, c0.Run(23));
[email protected]b38d3572011-02-15 01:27:38397
tzikb9499fd92016-10-12 04:55:02398 // BindRepeating can handle a RepeatingCallback as the target functor.
399 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
[email protected]b38d3572011-02-15 01:27:38400
tzikb9499fd92016-10-12 04:55:02401 // RepeatingCallback can run via a rvalue-reference.
402 EXPECT_EQ(42, std::move(c1).Run());
403
404 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
405 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
[email protected]b38d3572011-02-15 01:27:38406}
407
tzikb9499fd92016-10-12 04:55:02408TEST_F(BindTest, OnceCallbackBasicTest) {
409 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
[email protected]b38d3572011-02-15 01:27:38410
tzikb9499fd92016-10-12 04:55:02411 // OnceCallback can run via a rvalue-reference.
412 EXPECT_EQ(63, std::move(c0).Run(32));
413
414 // After running via the rvalue-reference, the value of the OnceCallback
415 // is undefined. The implementation simply clears the instance after the
416 // invocation.
417 EXPECT_TRUE(c0.is_null());
418
419 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
420
421 // BindOnce can handle a rvalue-reference of OnceCallback as the target
422 // functor.
423 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
424 EXPECT_EQ(41, std::move(c1).Run());
425
426 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
427 EXPECT_EQ(41, BindOnce(c2, 13).Run());
[email protected]b38d3572011-02-15 01:27:38428}
429
[email protected]7296f2762011-11-21 19:23:44430// IgnoreResult adapter test.
431// - Function with return value.
432// - Method with return value.
433// - Const Method with return.
434// - Method with return value bound to WeakPtr<>.
435// - Const Method with return bound to WeakPtr<>.
tzikb9499fd92016-10-12 04:55:02436TEST_F(BindTest, IgnoreResultForRepeating) {
[email protected]e8bfc31d2011-09-28 00:26:37437 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
[email protected]7296f2762011-11-21 19:23:44438 EXPECT_CALL(has_ref_, AddRef()).Times(2);
439 EXPECT_CALL(has_ref_, Release()).Times(2);
440 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
441 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
442 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
443 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
444
tzikb9499fd92016-10-12 04:55:02445 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
[email protected]7296f2762011-11-21 19:23:44446 normal_func_cb.Run();
447
tzikb9499fd92016-10-12 04:55:02448 RepeatingClosure non_void_method_cb =
449 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
[email protected]7296f2762011-11-21 19:23:44450 non_void_method_cb.Run();
451
tzikb9499fd92016-10-12 04:55:02452 RepeatingClosure non_void_const_method_cb =
453 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
[email protected]7296f2762011-11-21 19:23:44454 non_void_const_method_cb.Run();
455
456 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
457 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
458
tzikb9499fd92016-10-12 04:55:02459 RepeatingClosure non_void_weak_method_cb =
460 BindRepeating(IgnoreResult(&NoRef::IntMethod0),
461 weak_factory.GetWeakPtr());
[email protected]7296f2762011-11-21 19:23:44462 non_void_weak_method_cb.Run();
463
tzikb9499fd92016-10-12 04:55:02464 RepeatingClosure non_void_weak_const_method_cb =
465 BindRepeating(IgnoreResult(&NoRef::IntConstMethod0),
466 weak_factory.GetWeakPtr());
[email protected]7296f2762011-11-21 19:23:44467 non_void_weak_const_method_cb.Run();
468
469 weak_factory.InvalidateWeakPtrs();
470 non_void_weak_const_method_cb.Run();
471 non_void_weak_method_cb.Run();
[email protected]e8bfc31d2011-09-28 00:26:37472}
473
tzikb9499fd92016-10-12 04:55:02474TEST_F(BindTest, IgnoreResultForOnce) {
475 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
476 EXPECT_CALL(has_ref_, AddRef()).Times(2);
477 EXPECT_CALL(has_ref_, Release()).Times(2);
478 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
479 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
[email protected]b38d3572011-02-15 01:27:38480
tzikb9499fd92016-10-12 04:55:02481 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
482 std::move(normal_func_cb).Run();
[email protected]b38d3572011-02-15 01:27:38483
tzikb9499fd92016-10-12 04:55:02484 OnceClosure non_void_method_cb =
485 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
486 std::move(non_void_method_cb).Run();
[email protected]b38d3572011-02-15 01:27:38487
tzikb9499fd92016-10-12 04:55:02488 OnceClosure non_void_const_method_cb =
489 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
490 std::move(non_void_const_method_cb).Run();
[email protected]b38d3572011-02-15 01:27:38491
tzikb9499fd92016-10-12 04:55:02492 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
493 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
[email protected]b38d3572011-02-15 01:27:38494
tzikb9499fd92016-10-12 04:55:02495 OnceClosure non_void_weak_method_cb =
496 BindOnce(IgnoreResult(&NoRef::IntMethod0),
497 weak_factory.GetWeakPtr());
498 OnceClosure non_void_weak_const_method_cb =
499 BindOnce(IgnoreResult(&NoRef::IntConstMethod0),
500 weak_factory.GetWeakPtr());
[email protected]b38d3572011-02-15 01:27:38501
tzikb9499fd92016-10-12 04:55:02502 weak_factory.InvalidateWeakPtrs();
503 std::move(non_void_weak_const_method_cb).Run();
504 std::move(non_void_weak_method_cb).Run();
[email protected]c18b1052011-03-24 02:02:17505}
506
[email protected]b38d3572011-02-15 01:27:38507// Functions that take reference parameters.
508// - Forced reference parameter type still stores a copy.
509// - Forced const reference parameter type still stores a copy.
tzikb9499fd92016-10-12 04:55:02510TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
[email protected]b38d3572011-02-15 01:27:38511 int n = 1;
512 int& ref_n = n;
513 const int& const_ref_n = n;
514
tzikb9499fd92016-10-12 04:55:02515 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
[email protected]b38d3572011-02-15 01:27:38516 EXPECT_EQ(n, ref_copies_cb.Run());
517 n++;
518 EXPECT_EQ(n - 1, ref_copies_cb.Run());
519
tzikb9499fd92016-10-12 04:55:02520 RepeatingCallback<int()> const_ref_copies_cb =
521 BindRepeating(&Identity, const_ref_n);
[email protected]b38d3572011-02-15 01:27:38522 EXPECT_EQ(n, const_ref_copies_cb.Run());
523 n++;
524 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
525}
526
tzikb9499fd92016-10-12 04:55:02527TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
528 int n = 1;
529 int& ref_n = n;
530 const int& const_ref_n = n;
531
532 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
533 n++;
534 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
535
536 OnceCallback<int()> const_ref_copies_cb =
537 BindOnce(&Identity, const_ref_n);
538 n++;
539 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
540}
541
[email protected]b38d3572011-02-15 01:27:38542// Check that we can pass in arrays and have them be stored as a pointer.
543// - Array of values stores a pointer.
544// - Array of const values stores a pointer.
tzikb9499fd92016-10-12 04:55:02545TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
[email protected]b38d3572011-02-15 01:27:38546 int array[4] = {1, 1, 1, 1};
547 const int (*const_array_ptr)[4] = &array;
548
tzikb9499fd92016-10-12 04:55:02549 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
[email protected]b38d3572011-02-15 01:27:38550 EXPECT_EQ(1, array_cb.Run());
551
tzikb9499fd92016-10-12 04:55:02552 RepeatingCallback<int()> const_array_cb =
553 BindRepeating(&ArrayGet, *const_array_ptr, 1);
[email protected]b38d3572011-02-15 01:27:38554 EXPECT_EQ(1, const_array_cb.Run());
555
556 array[1] = 3;
557 EXPECT_EQ(3, array_cb.Run());
558 EXPECT_EQ(3, const_array_cb.Run());
559}
560
tzikb9499fd92016-10-12 04:55:02561TEST_F(BindTest, ArrayArgumentBindingForOnce) {
562 int array[4] = {1, 1, 1, 1};
563 const int (*const_array_ptr)[4] = &array;
[email protected]b38d3572011-02-15 01:27:38564
tzikb9499fd92016-10-12 04:55:02565 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
566 OnceCallback<int()> const_array_cb =
567 BindOnce(&ArrayGet, *const_array_ptr, 1);
[email protected]b38d3572011-02-15 01:27:38568
tzikb9499fd92016-10-12 04:55:02569 array[1] = 3;
570 EXPECT_EQ(3, std::move(array_cb).Run());
571 EXPECT_EQ(3, std::move(const_array_cb).Run());
[email protected]b38d3572011-02-15 01:27:38572}
573
[email protected]93540582011-05-16 22:35:14574// WeakPtr() support.
575// - Method bound to WeakPtr<> to non-const object.
576// - Const method bound to WeakPtr<> to non-const object.
577// - Const method bound to WeakPtr<> to const object.
578// - Normal Function with WeakPtr<> as P1 can have return type and is
579// not canceled.
tzikb9499fd92016-10-12 04:55:02580TEST_F(BindTest, WeakPtrForRepeating) {
[email protected]93540582011-05-16 22:35:14581 EXPECT_CALL(no_ref_, VoidMethod0());
582 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
583
584 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
585 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
586
tzikb9499fd92016-10-12 04:55:02587 RepeatingClosure method_cb =
588 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14589 method_cb.Run();
590
tzikb9499fd92016-10-12 04:55:02591 RepeatingClosure const_method_cb =
592 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14593 const_method_cb.Run();
594
tzikb9499fd92016-10-12 04:55:02595 RepeatingClosure const_method_const_ptr_cb =
596 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14597 const_method_const_ptr_cb.Run();
598
tzikb9499fd92016-10-12 04:55:02599 RepeatingCallback<int(int)> normal_func_cb =
600 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14601 EXPECT_EQ(1, normal_func_cb.Run(1));
602
603 weak_factory.InvalidateWeakPtrs();
604 const_weak_factory.InvalidateWeakPtrs();
605
606 method_cb.Run();
607 const_method_cb.Run();
608 const_method_const_ptr_cb.Run();
609
610 // Still runs even after the pointers are invalidated.
611 EXPECT_EQ(2, normal_func_cb.Run(2));
612}
613
tzikb9499fd92016-10-12 04:55:02614TEST_F(BindTest, WeakPtrForOnce) {
615 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
616 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_);
617
618 OnceClosure method_cb =
619 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
620 OnceClosure const_method_cb =
621 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
622 OnceClosure const_method_const_ptr_cb =
623 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
624 Callback<int(int)> normal_func_cb =
625 Bind(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
626
627 weak_factory.InvalidateWeakPtrs();
628 const_weak_factory.InvalidateWeakPtrs();
629
630 std::move(method_cb).Run();
631 std::move(const_method_cb).Run();
632 std::move(const_method_const_ptr_cb).Run();
633
634 // Still runs even after the pointers are invalidated.
635 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
636}
637
[email protected]b38d3572011-02-15 01:27:38638// ConstRef() wrapper support.
639// - Binding w/o ConstRef takes a copy.
640// - Binding a ConstRef takes a reference.
641// - Binding ConstRef to a function ConstRef does not copy on invoke.
tzikb9499fd92016-10-12 04:55:02642TEST_F(BindTest, ConstRefForRepeating) {
[email protected]b38d3572011-02-15 01:27:38643 int n = 1;
644
tzikb9499fd92016-10-12 04:55:02645 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
646 RepeatingCallback<int()> const_ref_cb = BindRepeating(&Identity, ConstRef(n));
[email protected]b38d3572011-02-15 01:27:38647 EXPECT_EQ(n, copy_cb.Run());
648 EXPECT_EQ(n, const_ref_cb.Run());
649 n++;
650 EXPECT_EQ(n - 1, copy_cb.Run());
651 EXPECT_EQ(n, const_ref_cb.Run());
652
653 int copies = 0;
654 int assigns = 0;
tzik52dcd672016-02-15 11:54:30655 int move_constructs = 0;
656 int move_assigns = 0;
657 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
tzikb9499fd92016-10-12 04:55:02658 RepeatingCallback<int()> all_const_ref_cb =
659 BindRepeating(&GetCopies, ConstRef(counter));
[email protected]b38d3572011-02-15 01:27:38660 EXPECT_EQ(0, all_const_ref_cb.Run());
661 EXPECT_EQ(0, copies);
662 EXPECT_EQ(0, assigns);
tzik52dcd672016-02-15 11:54:30663 EXPECT_EQ(0, move_constructs);
664 EXPECT_EQ(0, move_assigns);
[email protected]b38d3572011-02-15 01:27:38665}
666
tzikb9499fd92016-10-12 04:55:02667TEST_F(BindTest, ConstRefForOnce) {
668 int n = 1;
[email protected]edd2f1b2013-06-22 20:32:50669
tzikb9499fd92016-10-12 04:55:02670 OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
671 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, ConstRef(n));
672 n++;
673 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
674 EXPECT_EQ(n, std::move(const_ref_cb).Run());
675
676 int copies = 0;
677 int assigns = 0;
678 int move_constructs = 0;
679 int move_assigns = 0;
680 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
681 OnceCallback<int()> all_const_ref_cb =
682 BindOnce(&GetCopies, ConstRef(counter));
683 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
684 EXPECT_EQ(0, copies);
685 EXPECT_EQ(0, assigns);
686 EXPECT_EQ(0, move_constructs);
687 EXPECT_EQ(0, move_assigns);
[email protected]edd2f1b2013-06-22 20:32:50688}
689
[email protected]08aa4552011-10-15 00:34:42690// Test Owned() support.
tzikb9499fd92016-10-12 04:55:02691TEST_F(BindTest, OwnedForRepeating) {
[email protected]08aa4552011-10-15 00:34:42692 int deletes = 0;
693 DeleteCounter* counter = new DeleteCounter(&deletes);
694
695 // If we don't capture, delete happens on Callback destruction/reset.
696 // return the same value.
tzikb9499fd92016-10-12 04:55:02697 RepeatingCallback<DeleteCounter*()> no_capture_cb =
698 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
[email protected]206a2ae82011-12-22 21:12:58699 ASSERT_EQ(counter, no_capture_cb.Run());
700 ASSERT_EQ(counter, no_capture_cb.Run());
[email protected]08aa4552011-10-15 00:34:42701 EXPECT_EQ(0, deletes);
702 no_capture_cb.Reset(); // This should trigger a delete.
703 EXPECT_EQ(1, deletes);
704
705 deletes = 0;
706 counter = new DeleteCounter(&deletes);
tzikb9499fd92016-10-12 04:55:02707 RepeatingClosure own_object_cb =
708 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
[email protected]08aa4552011-10-15 00:34:42709 own_object_cb.Run();
710 EXPECT_EQ(0, deletes);
711 own_object_cb.Reset();
712 EXPECT_EQ(1, deletes);
713}
714
tzikb9499fd92016-10-12 04:55:02715TEST_F(BindTest, OwnedForOnce) {
716 int deletes = 0;
717 DeleteCounter* counter = new DeleteCounter(&deletes);
718
719 // If we don't capture, delete happens on Callback destruction/reset.
720 // return the same value.
721 OnceCallback<DeleteCounter*()> no_capture_cb =
722 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
723 EXPECT_EQ(0, deletes);
724 no_capture_cb.Reset(); // This should trigger a delete.
725 EXPECT_EQ(1, deletes);
726
727 deletes = 0;
728 counter = new DeleteCounter(&deletes);
729 OnceClosure own_object_cb =
730 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
731 EXPECT_EQ(0, deletes);
732 own_object_cb.Reset();
733 EXPECT_EQ(1, deletes);
734}
735
736template <typename T>
737class BindVariantsTest : public ::testing::Test {
738};
739
740struct RepeatingTestConfig {
741 template <typename Signature>
742 using CallbackType = RepeatingCallback<Signature>;
743 using ClosureType = RepeatingClosure;
744
745 template <typename F, typename... Args>
746 static CallbackType<MakeUnboundRunType<F, Args...>>
747 Bind(F&& f, Args&&... args) {
748 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
749 }
750};
751
752struct OnceTestConfig {
753 template <typename Signature>
754 using CallbackType = OnceCallback<Signature>;
755 using ClosureType = OnceClosure;
756
757 template <typename F, typename... Args>
758 static CallbackType<MakeUnboundRunType<F, Args...>>
759 Bind(F&& f, Args&&... args) {
760 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
761 }
762};
763
764using BindVariantsTestConfig = ::testing::Types<
765 RepeatingTestConfig, OnceTestConfig>;
766TYPED_TEST_CASE(BindVariantsTest, BindVariantsTestConfig);
767
768template <typename TypeParam, typename Signature>
769using CallbackType = typename TypeParam::template CallbackType<Signature>;
770
771// Function type support.
772// - Normal function.
773// - Normal function bound with non-refcounted first argument.
774// - Method bound to non-const object.
775// - Method bound to scoped_refptr.
776// - Const method bound to non-const object.
777// - Const method bound to const object.
778// - Derived classes can be used with pointers to non-virtual base functions.
779// - Derived classes can be used with pointers to virtual base functions (and
780// preserve virtual dispatch).
781TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
782 using ClosureType = typename TypeParam::ClosureType;
783
784 StrictMock<HasRef> has_ref;
785 StrictMock<NoRef> no_ref;
786 StrictMock<NoRef> static_func_mock;
787 const HasRef* const_has_ref_ptr = &has_ref;
788 g_func_mock_ptr = &static_func_mock;
789
790 EXPECT_CALL(static_func_mock, VoidMethod0());
791 EXPECT_CALL(has_ref, AddRef()).Times(4);
792 EXPECT_CALL(has_ref, Release()).Times(4);
793 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
794 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
795
796 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
797 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
798 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
799 std::move(normal_cb).Run();
800 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
801
802 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
kylechar973a0412017-09-26 18:40:29803 ClosureType method_refptr_cb =
804 TypeParam::Bind(&HasRef::VoidMethod0, WrapRefCounted(&has_ref));
tzikb9499fd92016-10-12 04:55:02805 ClosureType const_method_nonconst_obj_cb =
806 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
807 ClosureType const_method_const_obj_cb =
808 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
809 std::move(method_cb).Run();
810 std::move(method_refptr_cb).Run();
811 std::move(const_method_nonconst_obj_cb).Run();
812 std::move(const_method_const_obj_cb).Run();
813
814 Child child;
815 child.value = 0;
816 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
817 std::move(virtual_set_cb).Run();
818 EXPECT_EQ(kChildValue, child.value);
819
820 child.value = 0;
821 ClosureType non_virtual_set_cb =
822 TypeParam::Bind(&Parent::NonVirtualSet, &child);
823 std::move(non_virtual_set_cb).Run();
824 EXPECT_EQ(kParentValue, child.value);
825}
826
827// Return value support.
828// - Function with return value.
829// - Method with return value.
830// - Const method with return value.
831// - Move-only return value.
832TYPED_TEST(BindVariantsTest, ReturnValues) {
833 StrictMock<NoRef> static_func_mock;
834 StrictMock<HasRef> has_ref;
835 g_func_mock_ptr = &static_func_mock;
836 const HasRef* const_has_ref_ptr = &has_ref;
837
838 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
839 EXPECT_CALL(has_ref, AddRef()).Times(4);
840 EXPECT_CALL(has_ref, Release()).Times(4);
841 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
842 EXPECT_CALL(has_ref, IntConstMethod0())
843 .WillOnce(Return(41337))
844 .WillOnce(Return(51337));
845 EXPECT_CALL(has_ref, UniquePtrMethod0())
Jeremy Roman9532f252017-08-16 23:27:24846 .WillOnce(Return(ByMove(std::make_unique<int>(42))));
tzikb9499fd92016-10-12 04:55:02847
848 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
849 CallbackType<TypeParam, int()> method_cb =
850 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
851 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
852 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
853 CallbackType<TypeParam, int()> const_method_const_obj_cb =
854 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
855 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
856 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
857 EXPECT_EQ(1337, std::move(normal_cb).Run());
858 EXPECT_EQ(31337, std::move(method_cb).Run());
859 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
860 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
861 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
862}
863
864// Argument binding tests.
865// - Argument binding to primitive.
866// - Argument binding to primitive pointer.
867// - Argument binding to a literal integer.
868// - Argument binding to a literal string.
869// - Argument binding with template function.
870// - Argument binding to an object.
871// - Argument binding to pointer to incomplete type.
872// - Argument gets type converted.
873// - Pointer argument gets converted.
874// - Const Reference forces conversion.
875TYPED_TEST(BindVariantsTest, ArgumentBinding) {
876 int n = 2;
877
878 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
879 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
880 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
881 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
882 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
883
884 NoRefParent p;
885 p.value = 5;
886 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
887
888 IncompleteType* incomplete_ptr = reinterpret_cast<IncompleteType*>(123);
889 EXPECT_EQ(incomplete_ptr,
890 TypeParam::Bind(&PolymorphicIdentity<IncompleteType*>,
891 incomplete_ptr).Run());
892
893 NoRefChild c;
894 c.value = 6;
895 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
896
897 c.value = 7;
898 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
899
900 c.value = 8;
901 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
902}
903
904// Unbound argument type support tests.
905// - Unbound value.
906// - Unbound pointer.
907// - Unbound reference.
908// - Unbound const reference.
909// - Unbound unsized array.
910// - Unbound sized array.
911// - Unbound array-of-arrays.
912TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
913 CallbackType<TypeParam, void(int)> unbound_value_cb =
914 TypeParam::Bind(&VoidPolymorphic<int>::Run);
915 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
916 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
917 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
918 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
919 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
920 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
921 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
922 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
923 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
924 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
925 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
926 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
927 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
928 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
929}
930
931// Function with unbound reference parameter.
932// - Original parameter is modified by callback.
933TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
934 int n = 0;
935 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
936 TypeParam::Bind(&RefArgSet);
937 std::move(unbound_ref_cb).Run(n);
938 EXPECT_EQ(2, n);
939}
940
941// Unretained() wrapper support.
942// - Method bound to Unretained() non-const object.
943// - Const method bound to Unretained() non-const object.
944// - Const method bound to Unretained() const object.
945TYPED_TEST(BindVariantsTest, Unretained) {
946 StrictMock<NoRef> no_ref;
947 const NoRef* const_no_ref_ptr = &no_ref;
948
949 EXPECT_CALL(no_ref, VoidMethod0());
950 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
951
952 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
953 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
954 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
955}
956
957TYPED_TEST(BindVariantsTest, ScopedRefptr) {
958 StrictMock<HasRef> has_ref;
959 EXPECT_CALL(has_ref, AddRef()).Times(1);
960 EXPECT_CALL(has_ref, Release()).Times(1);
961
962 const scoped_refptr<HasRef> refptr(&has_ref);
963 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb =
964 TypeParam::Bind(&FunctionWithScopedRefptrFirstParam,
965 base::ConstRef(refptr), 1);
966 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
967}
968
969TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
tzik4435e8042016-05-11 23:05:05970 std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
971 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
tzikb9499fd92016-10-12 04:55:02972 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
tzik4435e8042016-05-11 23:05:05973}
974
dchengf10b7732016-01-21 19:37:55975// Tests for Passed() wrapper support:
[email protected]206a2ae82011-12-22 21:12:58976// - Passed() can be constructed from a pointer to scoper.
977// - Passed() can be constructed from a scoper rvalue.
978// - Using Passed() gives Callback Ownership.
979// - Ownership is transferred from Callback to callee on the first Run().
980// - Callback supports unbound arguments.
dchengf10b7732016-01-21 19:37:55981template <typename T>
982class BindMoveOnlyTypeTest : public ::testing::Test {
983};
984
985struct CustomDeleter {
986 void operator()(DeleteCounter* c) { delete c; }
987};
988
989using MoveOnlyTypesToTest =
dcheng093de9b2016-04-04 21:25:51990 ::testing::Types<std::unique_ptr<DeleteCounter>,
dchengf10b7732016-01-21 19:37:55991 std::unique_ptr<DeleteCounter, CustomDeleter>>;
992TYPED_TEST_CASE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
993
994TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
[email protected]206a2ae82011-12-22 21:12:58995 int deletes = 0;
996
dchengf10b7732016-01-21 19:37:55997 TypeParam ptr(new DeleteCounter(&deletes));
998 Callback<TypeParam()> callback = Bind(&PassThru<TypeParam>, Passed(&ptr));
[email protected]206a2ae82011-12-22 21:12:58999 EXPECT_FALSE(ptr.get());
1000 EXPECT_EQ(0, deletes);
1001
1002 // If we never invoke the Callback, it retains ownership and deletes.
[email protected]206a2ae82011-12-22 21:12:581003 callback.Reset();
[email protected]206a2ae82011-12-22 21:12:581004 EXPECT_EQ(1, deletes);
[email protected]206a2ae82011-12-22 21:12:581005}
1006
dchengf10b7732016-01-21 19:37:551007TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
dcheng69f2a042015-12-14 20:31:521008 int deletes = 0;
dchengf10b7732016-01-21 19:37:551009 Callback<TypeParam()> callback = Bind(
1010 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
dcheng69f2a042015-12-14 20:31:521011 EXPECT_EQ(0, deletes);
1012
1013 // If we never invoke the Callback, it retains ownership and deletes.
dchengf10b7732016-01-21 19:37:551014 callback.Reset();
dcheng69f2a042015-12-14 20:31:521015 EXPECT_EQ(1, deletes);
dchengf10b7732016-01-21 19:37:551016}
dcheng69f2a042015-12-14 20:31:521017
dchengf10b7732016-01-21 19:37:551018// Check that ownership can be transferred back out.
1019TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
1020 int deletes = 0;
dcheng69f2a042015-12-14 20:31:521021 DeleteCounter* counter = new DeleteCounter(&deletes);
dchengf10b7732016-01-21 19:37:551022 Callback<TypeParam()> callback =
1023 Bind(&PassThru<TypeParam>, Passed(TypeParam(counter)));
1024 TypeParam result = callback.Run();
dcheng69f2a042015-12-14 20:31:521025 ASSERT_EQ(counter, result.get());
1026 EXPECT_EQ(0, deletes);
1027
1028 // Resetting does not delete since ownership was transferred.
1029 callback.Reset();
1030 EXPECT_EQ(0, deletes);
1031
1032 // Ensure that we actually did get ownership.
1033 result.reset();
1034 EXPECT_EQ(1, deletes);
dchengf10b7732016-01-21 19:37:551035}
dcheng69f2a042015-12-14 20:31:521036
dchengf10b7732016-01-21 19:37:551037TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
1038 int deletes = 0;
1039 TypeParam ptr(new DeleteCounter(&deletes));
dcheng69f2a042015-12-14 20:31:521040 // Test unbound argument forwarding.
dchengf10b7732016-01-21 19:37:551041 Callback<TypeParam(TypeParam)> cb_unbound = Bind(&PassThru<TypeParam>);
dcheng69f2a042015-12-14 20:31:521042 cb_unbound.Run(std::move(ptr));
dchengf10b7732016-01-21 19:37:551043 EXPECT_EQ(1, deletes);
dcheng69f2a042015-12-14 20:31:521044}
1045
dcheng093de9b2016-04-04 21:25:511046void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
dcheng53b4cea2016-02-02 04:09:331047 ASSERT_EQ(1u, v.size());
1048 EXPECT_EQ(12345, *v[0]);
1049}
1050
dcheng093de9b2016-04-04 21:25:511051std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
1052 std::vector<std::unique_ptr<int>> v) {
dcheng53b4cea2016-02-02 04:09:331053 VerifyVector(v);
1054 return v;
1055}
1056
1057// Test that a vector containing move-only types can be used with Callback.
1058TEST_F(BindTest, BindMoveOnlyVector) {
dcheng093de9b2016-04-04 21:25:511059 using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
dcheng53b4cea2016-02-02 04:09:331060
1061 MoveOnlyVector v;
dcheng093de9b2016-04-04 21:25:511062 v.push_back(WrapUnique(new int(12345)));
dcheng53b4cea2016-02-02 04:09:331063
1064 // Early binding should work:
1065 base::Callback<MoveOnlyVector()> bound_cb =
1066 base::Bind(&AcceptAndReturnMoveOnlyVector, Passed(&v));
1067 MoveOnlyVector intermediate_result = bound_cb.Run();
1068 VerifyVector(intermediate_result);
1069
1070 // As should passing it as an argument to Run():
1071 base::Callback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
1072 base::Bind(&AcceptAndReturnMoveOnlyVector);
1073 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
1074 VerifyVector(final_result);
1075}
1076
tzik52dcd672016-02-15 11:54:301077// Argument copy-constructor usage for non-reference copy-only parameters.
[email protected]b38d3572011-02-15 01:27:381078// - Bound arguments are only copied once.
1079// - Forwarded arguments are only copied once.
[email protected]206a2ae82011-12-22 21:12:581080// - Forwarded arguments with coercions are only copied twice (once for the
1081// coercion, and one for the final dispatch).
[email protected]b38d3572011-02-15 01:27:381082TEST_F(BindTest, ArgumentCopies) {
1083 int copies = 0;
1084 int assigns = 0;
1085
1086 CopyCounter counter(&copies, &assigns);
tzik52dcd672016-02-15 11:54:301087 Bind(&VoidPolymorphic<CopyCounter>::Run, counter);
1088 EXPECT_EQ(1, copies);
[email protected]b38d3572011-02-15 01:27:381089 EXPECT_EQ(0, assigns);
1090
1091 copies = 0;
1092 assigns = 0;
tzik52dcd672016-02-15 11:54:301093 Bind(&VoidPolymorphic<CopyCounter>::Run, CopyCounter(&copies, &assigns));
1094 EXPECT_EQ(1, copies);
[email protected]b38d3572011-02-15 01:27:381095 EXPECT_EQ(0, assigns);
1096
1097 copies = 0;
1098 assigns = 0;
tzik52dcd672016-02-15 11:54:301099 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
tzika43eff02016-03-09 05:46:051100 EXPECT_EQ(2, copies);
[email protected]b38d3572011-02-15 01:27:381101 EXPECT_EQ(0, assigns);
tzik52dcd672016-02-15 11:54:301102
1103 copies = 0;
1104 assigns = 0;
1105 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(&copies, &assigns));
1106 EXPECT_EQ(1, copies);
1107 EXPECT_EQ(0, assigns);
1108
1109 copies = 0;
1110 assigns = 0;
1111 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
1112 Bind(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
1113 EXPECT_EQ(2, copies);
1114 EXPECT_EQ(0, assigns);
1115
1116 copies = 0;
1117 assigns = 0;
1118 Bind(&VoidPolymorphic<CopyCounter>::Run)
1119 .Run(CopyCounter(
1120 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
1121 EXPECT_EQ(2, copies);
1122 EXPECT_EQ(0, assigns);
1123}
1124
1125// Argument move-constructor usage for move-only parameters.
1126// - Bound arguments passed by move are not copied.
1127TEST_F(BindTest, ArgumentMoves) {
1128 int move_constructs = 0;
1129 int move_assigns = 0;
1130
1131 Bind(&VoidPolymorphic<const MoveCounter&>::Run,
1132 MoveCounter(&move_constructs, &move_assigns));
1133 EXPECT_EQ(1, move_constructs);
1134 EXPECT_EQ(0, move_assigns);
1135
1136 // TODO(tzik): Support binding move-only type into a non-reference parameter
1137 // of a variant of Callback.
1138
tzika43eff02016-03-09 05:46:051139 move_constructs = 0;
1140 move_assigns = 0;
1141 Bind(&VoidPolymorphic<MoveCounter>::Run)
1142 .Run(MoveCounter(&move_constructs, &move_assigns));
1143 EXPECT_EQ(1, move_constructs);
1144 EXPECT_EQ(0, move_assigns);
1145
1146 move_constructs = 0;
1147 move_assigns = 0;
1148 Bind(&VoidPolymorphic<MoveCounter>::Run)
1149 .Run(MoveCounter(DerivedCopyMoveCounter(
1150 nullptr, nullptr, &move_constructs, &move_assigns)));
1151 EXPECT_EQ(2, move_constructs);
1152 EXPECT_EQ(0, move_assigns);
tzik52dcd672016-02-15 11:54:301153}
1154
1155// Argument constructor usage for non-reference movable-copyable
1156// parameters.
1157// - Bound arguments passed by move are not copied.
1158// - Forwarded arguments are only copied once.
1159// - Forwarded arguments with coercions are only copied once and moved once.
1160TEST_F(BindTest, ArgumentCopiesAndMoves) {
1161 int copies = 0;
1162 int assigns = 0;
1163 int move_constructs = 0;
1164 int move_assigns = 0;
1165
1166 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
1167 Bind(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
1168 EXPECT_EQ(1, copies);
1169 EXPECT_EQ(0, assigns);
1170 EXPECT_EQ(0, move_constructs);
1171 EXPECT_EQ(0, move_assigns);
1172
1173 copies = 0;
1174 assigns = 0;
1175 move_constructs = 0;
1176 move_assigns = 0;
1177 Bind(&VoidPolymorphic<CopyMoveCounter>::Run,
1178 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1179 EXPECT_EQ(0, copies);
1180 EXPECT_EQ(0, assigns);
1181 EXPECT_EQ(1, 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).Run(counter);
1189 EXPECT_EQ(1, copies);
1190 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051191 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301192 EXPECT_EQ(0, move_assigns);
1193
tzik52dcd672016-02-15 11:54:301194 copies = 0;
1195 assigns = 0;
1196 move_constructs = 0;
1197 move_assigns = 0;
1198 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1199 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
tzika43eff02016-03-09 05:46:051200 EXPECT_EQ(0, copies);
tzik52dcd672016-02-15 11:54:301201 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 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1206 &move_assigns);
1207 copies = 0;
1208 assigns = 0;
1209 move_constructs = 0;
1210 move_assigns = 0;
1211 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1212 .Run(CopyMoveCounter(derived_counter));
tzika43eff02016-03-09 05:46:051213 EXPECT_EQ(1, copies);
tzik52dcd672016-02-15 11:54:301214 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051215 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301216 EXPECT_EQ(0, move_assigns);
1217
tzik52dcd672016-02-15 11:54:301218 copies = 0;
1219 assigns = 0;
1220 move_constructs = 0;
1221 move_assigns = 0;
1222 Bind(&VoidPolymorphic<CopyMoveCounter>::Run)
1223 .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1224 &copies, &assigns, &move_constructs, &move_assigns)));
tzika43eff02016-03-09 05:46:051225 EXPECT_EQ(0, copies);
tzik52dcd672016-02-15 11:54:301226 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051227 EXPECT_EQ(2, move_constructs);
tzik52dcd672016-02-15 11:54:301228 EXPECT_EQ(0, move_assigns);
[email protected]b38d3572011-02-15 01:27:381229}
1230
tzikc1db72652016-07-08 09:42:381231TEST_F(BindTest, CapturelessLambda) {
tzikf98654b2017-12-02 03:28:581232 EXPECT_FALSE(internal::IsCallableObject<void>::value);
1233 EXPECT_FALSE(internal::IsCallableObject<int>::value);
1234 EXPECT_FALSE(internal::IsCallableObject<void (*)()>::value);
1235 EXPECT_FALSE(internal::IsCallableObject<void (NoRef::*)()>::value);
tzikc1db72652016-07-08 09:42:381236
1237 auto f = []() {};
tzikf98654b2017-12-02 03:28:581238 EXPECT_TRUE(internal::IsCallableObject<decltype(f)>::value);
tzikc1db72652016-07-08 09:42:381239
1240 int i = 0;
krasin0a8923f2017-01-18 19:29:331241 auto g = [i]() { (void)i; };
tzikf98654b2017-12-02 03:28:581242 EXPECT_TRUE(internal::IsCallableObject<decltype(g)>::value);
tzikc1db72652016-07-08 09:42:381243
1244 auto h = [](int, double) { return 'k'; };
1245 EXPECT_TRUE((std::is_same<
1246 char(int, double),
1247 internal::ExtractCallableRunType<decltype(h)>>::value));
1248
1249 EXPECT_EQ(42, Bind([] { return 42; }).Run());
1250 EXPECT_EQ(42, Bind([](int i) { return i * 7; }, 6).Run());
1251
1252 int x = 1;
1253 base::Callback<void(int)> cb =
1254 Bind([](int* x, int i) { *x *= i; }, Unretained(&x));
1255 cb.Run(6);
1256 EXPECT_EQ(6, x);
1257 cb.Run(7);
1258 EXPECT_EQ(42, x);
1259}
1260
tzikf98654b2017-12-02 03:28:581261TEST_F(BindTest, EmptyFunctor) {
1262 struct NonEmptyFunctor {
1263 int operator()() const { return x; }
1264 int x = 42;
1265 };
1266
1267 struct EmptyFunctor {
1268 int operator()() { return 42; }
1269 };
1270
1271 struct EmptyFunctorConst {
1272 int operator()() const { return 42; }
1273 };
1274
1275 EXPECT_TRUE(internal::IsCallableObject<NonEmptyFunctor>::value);
1276 EXPECT_TRUE(internal::IsCallableObject<EmptyFunctor>::value);
1277 EXPECT_TRUE(internal::IsCallableObject<EmptyFunctorConst>::value);
1278 EXPECT_EQ(42, BindOnce(EmptyFunctor()).Run());
1279 EXPECT_EQ(42, BindOnce(EmptyFunctorConst()).Run());
1280 EXPECT_EQ(42, BindRepeating(EmptyFunctorConst()).Run());
1281}
1282
1283TEST_F(BindTest, CapturingLambdaForTesting) {
tzik4b83dce2017-12-04 19:04:271284 int x = 6;
1285 EXPECT_EQ(42, BindLambdaForTesting([=](int y) { return x * y; }).Run(7));
tzikf98654b2017-12-02 03:28:581286
tzik4b83dce2017-12-04 19:04:271287 auto f = [x](std::unique_ptr<int> y) { return x * *y; };
1288 EXPECT_EQ(42, BindLambdaForTesting(f).Run(std::make_unique<int>(7)));
tzikf98654b2017-12-02 03:28:581289}
1290
tzik59aa6bb12016-09-08 10:58:531291TEST_F(BindTest, Cancellation) {
dcheng172b6ad2016-09-24 05:05:571292 EXPECT_CALL(no_ref_, VoidMethodWithIntArg(_)).Times(2);
tzik59aa6bb12016-09-08 10:58:531293
1294 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
tzik44adf072016-10-07 04:34:541295 RepeatingCallback<void(int)> cb =
1296 BindRepeating(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1297 RepeatingClosure cb2 = BindRepeating(cb, 8);
1298 OnceClosure cb3 = BindOnce(cb, 8);
1299
1300 OnceCallback<void(int)> cb4 =
1301 BindOnce(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1302 EXPECT_FALSE(cb4.IsCancelled());
1303
1304 OnceClosure cb5 = BindOnce(std::move(cb4), 8);
tzik59aa6bb12016-09-08 10:58:531305
1306 EXPECT_FALSE(cb.IsCancelled());
1307 EXPECT_FALSE(cb2.IsCancelled());
tzik44adf072016-10-07 04:34:541308 EXPECT_FALSE(cb3.IsCancelled());
1309 EXPECT_FALSE(cb5.IsCancelled());
tzik59aa6bb12016-09-08 10:58:531310
dcheng172b6ad2016-09-24 05:05:571311 cb.Run(6);
tzik59aa6bb12016-09-08 10:58:531312 cb2.Run();
1313
1314 weak_factory.InvalidateWeakPtrs();
1315
1316 EXPECT_TRUE(cb.IsCancelled());
1317 EXPECT_TRUE(cb2.IsCancelled());
tzik44adf072016-10-07 04:34:541318 EXPECT_TRUE(cb3.IsCancelled());
1319 EXPECT_TRUE(cb5.IsCancelled());
tzik59aa6bb12016-09-08 10:58:531320
dcheng172b6ad2016-09-24 05:05:571321 cb.Run(6);
tzik59aa6bb12016-09-08 10:58:531322 cb2.Run();
tzik44adf072016-10-07 04:34:541323 std::move(cb3).Run();
1324 std::move(cb5).Run();
tzik59aa6bb12016-09-08 10:58:531325}
1326
tzik27d1e312016-09-13 05:28:591327TEST_F(BindTest, OnceCallback) {
tzik27d1e312016-09-13 05:28:591328 // Check if Callback variants have declarations of conversions as expected.
1329 // Copy constructor and assignment of RepeatingCallback.
1330 static_assert(std::is_constructible<
1331 RepeatingClosure, const RepeatingClosure&>::value,
1332 "RepeatingClosure should be copyable.");
danakj560f5dd22017-04-04 20:55:291333 static_assert(
1334 std::is_assignable<RepeatingClosure, const RepeatingClosure&>::value,
tzik27d1e312016-09-13 05:28:591335 "RepeatingClosure should be copy-assignable.");
1336
1337 // Move constructor and assignment of RepeatingCallback.
1338 static_assert(std::is_constructible<
1339 RepeatingClosure, RepeatingClosure&&>::value,
1340 "RepeatingClosure should be movable.");
danakj560f5dd22017-04-04 20:55:291341 static_assert(std::is_assignable<RepeatingClosure, RepeatingClosure&&>::value,
1342 "RepeatingClosure should be move-assignable");
tzik27d1e312016-09-13 05:28:591343
1344 // Conversions from OnceCallback to RepeatingCallback.
1345 static_assert(!std::is_constructible<
1346 RepeatingClosure, const OnceClosure&>::value,
1347 "OnceClosure should not be convertible to RepeatingClosure.");
danakj560f5dd22017-04-04 20:55:291348 static_assert(
1349 !std::is_assignable<RepeatingClosure, const OnceClosure&>::value,
tzik27d1e312016-09-13 05:28:591350 "OnceClosure should not be convertible to RepeatingClosure.");
1351
1352 // Destructive conversions from OnceCallback to RepeatingCallback.
1353 static_assert(!std::is_constructible<
1354 RepeatingClosure, OnceClosure&&>::value,
1355 "OnceClosure should not be convertible to RepeatingClosure.");
danakj560f5dd22017-04-04 20:55:291356 static_assert(!std::is_assignable<RepeatingClosure, OnceClosure&&>::value,
1357 "OnceClosure should not be convertible to RepeatingClosure.");
tzik27d1e312016-09-13 05:28:591358
1359 // Copy constructor and assignment of OnceCallback.
1360 static_assert(!std::is_constructible<
1361 OnceClosure, const OnceClosure&>::value,
1362 "OnceClosure should not be copyable.");
danakj560f5dd22017-04-04 20:55:291363 static_assert(!std::is_assignable<OnceClosure, const OnceClosure&>::value,
1364 "OnceClosure should not be copy-assignable");
tzik27d1e312016-09-13 05:28:591365
1366 // Move constructor and assignment of OnceCallback.
1367 static_assert(std::is_constructible<
1368 OnceClosure, OnceClosure&&>::value,
1369 "OnceClosure should be movable.");
danakj560f5dd22017-04-04 20:55:291370 static_assert(std::is_assignable<OnceClosure, OnceClosure&&>::value,
1371 "OnceClosure should be move-assignable.");
tzik27d1e312016-09-13 05:28:591372
1373 // Conversions from RepeatingCallback to OnceCallback.
1374 static_assert(std::is_constructible<
1375 OnceClosure, const RepeatingClosure&>::value,
1376 "RepeatingClosure should be convertible to OnceClosure.");
danakj560f5dd22017-04-04 20:55:291377 static_assert(std::is_assignable<OnceClosure, const RepeatingClosure&>::value,
1378 "RepeatingClosure should be convertible to OnceClosure.");
tzik27d1e312016-09-13 05:28:591379
1380 // Destructive conversions from RepeatingCallback to OnceCallback.
1381 static_assert(std::is_constructible<
1382 OnceClosure, RepeatingClosure&&>::value,
1383 "RepeatingClosure should be convertible to OnceClosure.");
danakj560f5dd22017-04-04 20:55:291384 static_assert(std::is_assignable<OnceClosure, RepeatingClosure&&>::value,
1385 "RepeatingClosure should be covretible to OnceClosure.");
tzik27d1e312016-09-13 05:28:591386
1387 OnceClosure cb = BindOnce(&VoidPolymorphic<>::Run);
1388 std::move(cb).Run();
1389
1390 // RepeatingCallback should be convertible to OnceCallback.
1391 OnceClosure cb2 = BindRepeating(&VoidPolymorphic<>::Run);
1392 std::move(cb2).Run();
1393
1394 RepeatingClosure cb3 = BindRepeating(&VoidPolymorphic<>::Run);
1395 cb = cb3;
1396 std::move(cb).Run();
1397
1398 cb = std::move(cb2);
1399
Jeremy Roman9532f252017-08-16 23:27:241400 OnceCallback<void(int)> cb4 =
1401 BindOnce(&VoidPolymorphic<std::unique_ptr<int>, int>::Run,
1402 std::make_unique<int>(0));
tzik27d1e312016-09-13 05:28:591403 BindOnce(std::move(cb4), 1).Run();
1404}
1405
[email protected]b38d3572011-02-15 01:27:381406// Callback construction and assignment tests.
1407// - Construction from an InvokerStorageHolder should not cause ref/deref.
1408// - Assignment from other callback should only cause one ref
1409//
1410// TODO(ajwong): Is there actually a way to test this?
1411
[email protected]054ac7542011-02-27 01:25:591412#if defined(OS_WIN)
1413int __fastcall FastCallFunc(int n) {
1414 return n;
1415}
1416
1417int __stdcall StdCallFunc(int n) {
1418 return n;
1419}
1420
1421// Windows specific calling convention support.
1422// - Can bind a __fastcall function.
1423// - Can bind a __stdcall function.
1424TEST_F(BindTest, WindowsCallingConventions) {
tzik3bc7779b2015-12-19 09:18:461425 Callback<int()> fastcall_cb = Bind(&FastCallFunc, 1);
[email protected]054ac7542011-02-27 01:25:591426 EXPECT_EQ(1, fastcall_cb.Run());
1427
tzik3bc7779b2015-12-19 09:18:461428 Callback<int()> stdcall_cb = Bind(&StdCallFunc, 2);
[email protected]054ac7542011-02-27 01:25:591429 EXPECT_EQ(2, stdcall_cb.Run());
1430}
1431#endif
1432
[email protected]8cf362c2012-11-20 08:28:141433// Test null callbacks cause a DCHECK.
1434TEST(BindDeathTest, NullCallback) {
1435 base::Callback<void(int)> null_cb;
1436 ASSERT_TRUE(null_cb.is_null());
gab5e69cff2016-08-05 03:25:401437 EXPECT_DCHECK_DEATH(base::Bind(null_cb, 42));
[email protected]8cf362c2012-11-20 08:28:141438}
1439
[email protected]b38d3572011-02-15 01:27:381440} // namespace
1441} // namespace base