blob: 6f1eb43ccb3b5d9baf029ddab4324ac9a618ab2b [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
[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
Daniel Chengcd23b8b2022-09-16 17:16:245#include "base/functional/bind.h"
[email protected]b38d3572011-02-15 01:27:386
jdoerrie9d7236f62019-03-05 13:00:237#include <functional>
dcheng69f2a042015-12-14 20:31:528#include <memory>
Peter Kastinga16713f2023-09-02 23:03:109#include <string>
dcheng69f2a042015-12-14 20:31:5210#include <utility>
dcheng53b4cea2016-02-02 04:09:3311#include <vector>
dcheng69f2a042015-12-14 20:31:5212
Paul Semelb0ce4842022-09-28 08:09:5313#include "base/allocator/partition_alloc_features.h"
14#include "base/allocator/partition_alloc_support.h"
Arthur Sonzogni44769c82025-12-12 16:01:4215#include "base/compiler_specific.h"
Daniel Chengcd23b8b2022-09-16 17:16:2416#include "base/functional/callback.h"
Lei Zhang8a5af1992025-06-07 07:15:4517#include "base/logging.h"
dcheng093de9b2016-04-04 21:25:5118#include "base/memory/ptr_util.h"
Lukasz Anforowicz34d1682a2021-11-19 17:12:1719#include "base/memory/raw_ptr.h"
danakj92061c12022-07-28 23:53:5020#include "base/memory/raw_ref.h"
[email protected]206a2ae82011-12-22 21:12:5821#include "base/memory/ref_counted.h"
[email protected]206a2ae82011-12-22 21:12:5822#include "base/memory/weak_ptr.h"
danakj779e8302020-10-27 18:35:5823#include "base/strings/string_number_conversions.h"
Guido Urdanetaef4e91942020-11-09 15:06:2424#include "base/test/bind.h"
gabc964a852016-08-01 16:39:5625#include "base/test/gtest_util.h"
Paul Semelb0ce4842022-09-28 08:09:5326#include "base/test/scoped_feature_list.h"
avi9b6f42932015-12-26 22:15:1427#include "build/build_config.h"
Arthur Sonzognifd39d612024-06-26 08:16:2328#include "partition_alloc/buildflags.h"
Yuki Shiino985ab91e2024-03-14 07:20:4629#include "partition_alloc/dangling_raw_ptr_checks.h"
Yuki Shiino985ab91e2024-03-14 07:20:4630#include "partition_alloc/partition_alloc_for_testing.h"
31#include "partition_alloc/partition_root.h"
[email protected]b38d3572011-02-15 01:27:3832#include "testing/gmock/include/gmock/gmock.h"
33#include "testing/gtest/include/gtest/gtest.h"
34
Daniel Cheng91f6fbaf2022-09-16 12:07:4835using ::testing::_;
tzikefea4f52018-08-02 15:20:4636using ::testing::AnyNumber;
tzikb9499fd92016-10-12 04:55:0237using ::testing::ByMove;
tzikefea4f52018-08-02 15:20:4638using ::testing::Mock;
[email protected]b38d3572011-02-15 01:27:3839using ::testing::Return;
40using ::testing::StrictMock;
41
42namespace base {
43namespace {
44
[email protected]b38d3572011-02-15 01:27:3845class NoRef {
46 public:
Chris Watkinsbb7211c2017-11-29 07:16:3847 NoRef() = default;
David Bienvenub4b441e2020-09-23 05:49:5748 NoRef(const NoRef&) = delete;
49 // Particularly important in this test to ensure no copies are made.
50 NoRef& operator=(const NoRef&) = delete;
[email protected]b38d3572011-02-15 01:27:3851
tzik3bc7779b2015-12-19 09:18:4652 MOCK_METHOD0(VoidMethod0, void());
53 MOCK_CONST_METHOD0(VoidConstMethod0, void());
[email protected]b38d3572011-02-15 01:27:3854
tzik3bc7779b2015-12-19 09:18:4655 MOCK_METHOD0(IntMethod0, int());
56 MOCK_CONST_METHOD0(IntConstMethod0, int());
[email protected]b38d3572011-02-15 01:27:3857
dcheng172b6ad2016-09-24 05:05:5758 MOCK_METHOD1(VoidMethodWithIntArg, void(int));
tzikb9499fd92016-10-12 04:55:0259 MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
[email protected]b38d3572011-02-15 01:27:3860};
61
62class HasRef : public NoRef {
63 public:
Chris Watkinsbb7211c2017-11-29 07:16:3864 HasRef() = default;
David Bienvenub4b441e2020-09-23 05:49:5765 HasRef(const HasRef&) = delete;
66 // Particularly important in this test to ensure no copies are made.
67 HasRef& operator=(const HasRef&) = delete;
[email protected]b38d3572011-02-15 01:27:3868
tzik3bc7779b2015-12-19 09:18:4669 MOCK_CONST_METHOD0(AddRef, void());
70 MOCK_CONST_METHOD0(Release, bool());
tzikefea4f52018-08-02 15:20:4671 MOCK_CONST_METHOD0(HasAtLeastOneRef, bool());
[email protected]b38d3572011-02-15 01:27:3872};
73
[email protected]690bda882011-04-13 22:40:4674class HasRefPrivateDtor : public HasRef {
75 private:
Chris Watkinsbb7211c2017-11-29 07:16:3876 ~HasRefPrivateDtor() = default;
[email protected]690bda882011-04-13 22:40:4677};
78
[email protected]b38d3572011-02-15 01:27:3879static const int kParentValue = 1;
80static const int kChildValue = 2;
81
82class Parent {
83 public:
tzik3bc7779b2015-12-19 09:18:4684 void AddRef() const {}
85 void Release() const {}
tzikefea4f52018-08-02 15:20:4686 bool HasAtLeastOneRef() const { return true; }
[email protected]b38d3572011-02-15 01:27:3887 virtual void VirtualSet() { value = kParentValue; }
88 void NonVirtualSet() { value = kParentValue; }
89 int value;
90};
91
92class Child : public Parent {
93 public:
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
98class NoRefParent {
99 public:
100 virtual void VirtualSet() { value = kParentValue; }
101 void NonVirtualSet() { value = kParentValue; }
102 int value;
103};
104
105class NoRefChild : public NoRefParent {
dcheng56488182014-10-21 10:54:51106 void VirtualSet() override { value = kChildValue; }
[email protected]b38d3572011-02-15 01:27:38107 void NonVirtualSet() { value = kChildValue; }
108};
109
tzik52dcd672016-02-15 11:54:30110// Used for probing the number of copies and moves that occur if a type must be
111// coerced during argument forwarding in the Run() methods.
112struct DerivedCopyMoveCounter {
113 DerivedCopyMoveCounter(int* copies,
114 int* assigns,
115 int* move_constructs,
116 int* move_assigns)
117 : copies_(copies),
118 assigns_(assigns),
119 move_constructs_(move_constructs),
120 move_assigns_(move_assigns) {}
Keishi Hattori0e45c022021-11-27 09:25:52121 raw_ptr<int> copies_;
122 raw_ptr<int> assigns_;
123 raw_ptr<int> move_constructs_;
124 raw_ptr<int> move_assigns_;
[email protected]b38d3572011-02-15 01:27:38125};
126
tzik52dcd672016-02-15 11:54:30127// Used for probing the number of copies and moves in an argument.
128class CopyMoveCounter {
[email protected]b38d3572011-02-15 01:27:38129 public:
tzik52dcd672016-02-15 11:54:30130 CopyMoveCounter(int* copies,
131 int* assigns,
132 int* move_constructs,
133 int* move_assigns)
134 : copies_(copies),
135 assigns_(assigns),
136 move_constructs_(move_constructs),
137 move_assigns_(move_assigns) {}
138
139 CopyMoveCounter(const CopyMoveCounter& other)
140 : copies_(other.copies_),
141 assigns_(other.assigns_),
142 move_constructs_(other.move_constructs_),
143 move_assigns_(other.move_assigns_) {
144 (*copies_)++;
[email protected]b38d3572011-02-15 01:27:38145 }
146
tzik52dcd672016-02-15 11:54:30147 CopyMoveCounter(CopyMoveCounter&& other)
[email protected]b38d3572011-02-15 01:27:38148 : copies_(other.copies_),
tzik52dcd672016-02-15 11:54:30149 assigns_(other.assigns_),
150 move_constructs_(other.move_constructs_),
151 move_assigns_(other.move_assigns_) {
152 (*move_constructs_)++;
[email protected]b38d3572011-02-15 01:27:38153 }
154
[email protected]206a2ae82011-12-22 21:12:58155 // Probing for copies from coercion.
tzik52dcd672016-02-15 11:54:30156 explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
[email protected]b38d3572011-02-15 01:27:38157 : copies_(other.copies_),
tzik52dcd672016-02-15 11:54:30158 assigns_(other.assigns_),
159 move_constructs_(other.move_constructs_),
160 move_assigns_(other.move_assigns_) {
[email protected]b38d3572011-02-15 01:27:38161 (*copies_)++;
162 }
163
tzik52dcd672016-02-15 11:54:30164 // Probing for moves from coercion.
165 explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
166 : copies_(other.copies_),
167 assigns_(other.assigns_),
168 move_constructs_(other.move_constructs_),
169 move_assigns_(other.move_assigns_) {
170 (*move_constructs_)++;
171 }
172
173 const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
[email protected]b38d3572011-02-15 01:27:38174 copies_ = rhs.copies_;
175 assigns_ = rhs.assigns_;
tzik52dcd672016-02-15 11:54:30176 move_constructs_ = rhs.move_constructs_;
177 move_assigns_ = rhs.move_assigns_;
[email protected]b38d3572011-02-15 01:27:38178
tzik52dcd672016-02-15 11:54:30179 (*assigns_)++;
180
181 return *this;
182 }
183
184 const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
185 copies_ = rhs.copies_;
186 assigns_ = rhs.assigns_;
187 move_constructs_ = rhs.move_constructs_;
188 move_assigns_ = rhs.move_assigns_;
189
190 (*move_assigns_)++;
[email protected]b38d3572011-02-15 01:27:38191
192 return *this;
193 }
194
Daniel Cheng91f6fbaf2022-09-16 12:07:48195 int copies() const { return *copies_; }
[email protected]b38d3572011-02-15 01:27:38196
[email protected]b38d3572011-02-15 01:27:38197 private:
Keishi Hattori0e45c022021-11-27 09:25:52198 raw_ptr<int> copies_;
199 raw_ptr<int> assigns_;
200 raw_ptr<int> move_constructs_;
201 raw_ptr<int> move_assigns_;
tzik52dcd672016-02-15 11:54:30202};
203
204// Used for probing the number of copies in an argument. The instance is a
205// copyable and non-movable type.
206class CopyCounter {
207 public:
208 CopyCounter(int* copies, int* assigns)
209 : counter_(copies, assigns, nullptr, nullptr) {}
Chris Watkinsbb7211c2017-11-29 07:16:38210 CopyCounter(const CopyCounter& other) = default;
211 CopyCounter& operator=(const CopyCounter& other) = default;
tzik52dcd672016-02-15 11:54:30212
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:
Daniel Cheng91f6fbaf2022-09-16 12:07:48242 explicit DeleteCounter(int* deletes) : deletes_(deletes) {}
[email protected]08aa4552011-10-15 00:34:42243
Daniel Cheng91f6fbaf2022-09-16 12:07:48244 ~DeleteCounter() { (*deletes_)++; }
[email protected]08aa4552011-10-15 00:34:42245
246 void VoidMethod0() {}
247
248 private:
Keishi Hattori0e45c022021-11-27 09:25:52249 raw_ptr<int> deletes_;
[email protected]08aa4552011-10-15 00:34:42250};
251
[email protected]206a2ae82011-12-22 21:12:58252template <typename T>
253T PassThru(T scoper) {
dcheng69f2a042015-12-14 20:31:52254 return scoper;
[email protected]206a2ae82011-12-22 21:12:58255}
256
[email protected]b38d3572011-02-15 01:27:38257// Some test functions that we can Bind to.
258template <typename T>
259T PolymorphicIdentity(T t) {
260 return t;
261}
262
tzik7fe3a682015-12-18 02:23:26263template <typename... Ts>
264struct VoidPolymorphic {
265 static void Run(Ts... t) {}
266};
[email protected]b38d3572011-02-15 01:27:38267
268int Identity(int n) {
269 return n;
270}
271
272int ArrayGet(const int array[], int n) {
Arthur Sonzogni44769c82025-12-12 16:01:42273 return UNSAFE_TODO(array[n]);
[email protected]b38d3572011-02-15 01:27:38274}
275
276int Sum(int a, int b, int c, int d, int e, int f) {
277 return a + b + c + d + e + f;
278}
279
280const char* CStringIdentity(const char* s) {
281 return s;
282}
283
tzik52dcd672016-02-15 11:54:30284int GetCopies(const CopyMoveCounter& counter) {
[email protected]b38d3572011-02-15 01:27:38285 return counter.copies();
286}
287
288int UnwrapNoRefParent(NoRefParent p) {
289 return p.value;
290}
291
292int UnwrapNoRefParentPtr(NoRefParent* p) {
293 return p->value;
294}
295
296int UnwrapNoRefParentConstRef(const NoRefParent& p) {
297 return p.value;
298}
299
Daniel Cheng91f6fbaf2022-09-16 12:07:48300void RefArgSet(int& n) {
[email protected]c18b1052011-03-24 02:02:17301 n = 2;
302}
303
Daniel Cheng91f6fbaf2022-09-16 12:07:48304void PtrArgSet(int* n) {
[email protected]e24f8762011-12-20 00:10:04305 *n = 2;
306}
307
[email protected]93540582011-05-16 22:35:14308int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
309 return n;
310}
311
[email protected]edd2f1b2013-06-22 20:32:50312int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
313 return n;
314}
315
kylechar650caf02019-07-17 03:25:41316void TakesACallback(const RepeatingClosure& callback) {
[email protected]e24f8762011-12-20 00:10:04317 callback.Run();
318}
319
tzikd58a89232018-04-26 04:29:53320int Noexcept() noexcept {
321 return 42;
322}
323
Ian McKellar29f262d2022-07-20 20:23:41324class NoexceptFunctor {
325 public:
326 int operator()() noexcept { return 42; }
327};
328
329class ConstNoexceptFunctor {
330 public:
331 int operator()() noexcept { return 42; }
332};
333
[email protected]b38d3572011-02-15 01:27:38334class BindTest : public ::testing::Test {
335 public:
336 BindTest() {
337 const_has_ref_ptr_ = &has_ref_;
338 const_no_ref_ptr_ = &no_ref_;
339 static_func_mock_ptr = &static_func_mock_;
340 }
David Bienvenub4b441e2020-09-23 05:49:57341 BindTest(const BindTest&) = delete;
342 BindTest& operator=(const BindTest&) = delete;
Daniel Chengc8f0b402018-04-27 17:28:20343 ~BindTest() override = default;
[email protected]b38d3572011-02-15 01:27:38344
Daniel Cheng91f6fbaf2022-09-16 12:07:48345 static void VoidFunc0() { static_func_mock_ptr->VoidMethod0(); }
[email protected]b38d3572011-02-15 01:27:38346
tzik3bc7779b2015-12-19 09:18:46347 static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
tzikd58a89232018-04-26 04:29:53348 int NoexceptMethod() noexcept { return 42; }
349 int ConstNoexceptMethod() const noexcept { return 42; }
[email protected]b38d3572011-02-15 01:27:38350
351 protected:
352 StrictMock<NoRef> no_ref_;
353 StrictMock<HasRef> has_ref_;
Keishi Hattori0e45c022021-11-27 09:25:52354 raw_ptr<const HasRef> const_has_ref_ptr_;
355 raw_ptr<const NoRef> const_no_ref_ptr_;
[email protected]b38d3572011-02-15 01:27:38356 StrictMock<NoRef> static_func_mock_;
357
358 // Used by the static functions to perform expectations.
359 static StrictMock<NoRef>* static_func_mock_ptr;
[email protected]b38d3572011-02-15 01:27:38360};
361
362StrictMock<NoRef>* BindTest::static_func_mock_ptr;
tzikb9499fd92016-10-12 04:55:02363StrictMock<NoRef>* g_func_mock_ptr;
364
365void VoidFunc0() {
366 g_func_mock_ptr->VoidMethod0();
367}
368
369int IntFunc0() {
370 return g_func_mock_ptr->IntMethod0();
371}
[email protected]b38d3572011-02-15 01:27:38372
tzik4d4da502016-08-23 04:23:49373TEST_F(BindTest, BasicTest) {
kylechar650caf02019-07-17 03:25:41374 RepeatingCallback<int(int, int, int)> cb = BindRepeating(&Sum, 32, 16, 8);
tzik4d4da502016-08-23 04:23:49375 EXPECT_EQ(92, cb.Run(13, 12, 11));
[email protected]b38d3572011-02-15 01:27:38376
kylechar650caf02019-07-17 03:25:41377 RepeatingCallback<int(int, int, int, int, int, int)> c1 = BindRepeating(&Sum);
tzik4d4da502016-08-23 04:23:49378 EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
[email protected]b38d3572011-02-15 01:27:38379
kylechar650caf02019-07-17 03:25:41380 RepeatingCallback<int(int, int, int)> c2 = BindRepeating(c1, 32, 16, 8);
tzik4d4da502016-08-23 04:23:49381 EXPECT_EQ(86, c2.Run(11, 10, 9));
[email protected]b38d3572011-02-15 01:27:38382
kylechar650caf02019-07-17 03:25:41383 RepeatingCallback<int()> c3 = BindRepeating(c2, 4, 2, 1);
tzik4d4da502016-08-23 04:23:49384 EXPECT_EQ(63, c3.Run());
[email protected]cea20fe42011-09-30 09:09:34385}
386
kylechar650caf02019-07-17 03:25:41387// Test that currying the rvalue result of another BindRepeating() works
388// correctly.
389// - rvalue should be usable as argument to BindRepeating().
390// - multiple runs of resulting RepeatingCallback remain valid.
[email protected]e24f8762011-12-20 00:10:04391TEST_F(BindTest, CurryingRvalueResultOfBind) {
392 int n = 0;
Daniel Cheng91f6fbaf2022-09-16 12:07:48393 RepeatingClosure cb =
394 BindRepeating(&TakesACallback, BindRepeating(&PtrArgSet, &n));
[email protected]e24f8762011-12-20 00:10:04395
kylechar650caf02019-07-17 03:25:41396 // If we implement BindRepeating() such that the return value has
397 // auto_ptr-like semantics, the second call here will fail because ownership
398 // of the internal BindState<> would have been transferred to a *temporary*
399 // construction of a RepeatingCallback object on the first call.
[email protected]e24f8762011-12-20 00:10:04400 cb.Run();
401 EXPECT_EQ(2, n);
402
403 n = 0;
404 cb.Run();
405 EXPECT_EQ(2, n);
406}
407
tzikb9499fd92016-10-12 04:55:02408TEST_F(BindTest, RepeatingCallbackBasicTest) {
409 RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
[email protected]b38d3572011-02-15 01:27:38410
tzikb9499fd92016-10-12 04:55:02411 // RepeatingCallback can run via a lvalue-reference.
412 EXPECT_EQ(63, c0.Run(32));
[email protected]81814bce2011-09-10 03:03:00413
tzikb9499fd92016-10-12 04:55:02414 // It is valid to call a RepeatingCallback more than once.
415 EXPECT_EQ(54, c0.Run(23));
[email protected]b38d3572011-02-15 01:27:38416
tzikb9499fd92016-10-12 04:55:02417 // BindRepeating can handle a RepeatingCallback as the target functor.
418 RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
[email protected]b38d3572011-02-15 01:27:38419
tzikb9499fd92016-10-12 04:55:02420 // RepeatingCallback can run via a rvalue-reference.
421 EXPECT_EQ(42, std::move(c1).Run());
422
423 // BindRepeating can handle a rvalue-reference of RepeatingCallback.
424 EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
[email protected]b38d3572011-02-15 01:27:38425}
426
tzikb9499fd92016-10-12 04:55:02427TEST_F(BindTest, OnceCallbackBasicTest) {
428 OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
[email protected]b38d3572011-02-15 01:27:38429
tzikb9499fd92016-10-12 04:55:02430 // OnceCallback can run via a rvalue-reference.
431 EXPECT_EQ(63, std::move(c0).Run(32));
432
433 // After running via the rvalue-reference, the value of the OnceCallback
434 // is undefined. The implementation simply clears the instance after the
435 // invocation.
Peter Kasting6218bbad2025-01-10 11:26:40436 EXPECT_TRUE(c0.is_null()); // NOLINT(bugprone-use-after-move)
tzikb9499fd92016-10-12 04:55:02437
438 c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
439
440 // BindOnce can handle a rvalue-reference of OnceCallback as the target
441 // functor.
442 OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
443 EXPECT_EQ(41, std::move(c1).Run());
444
445 RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
446 EXPECT_EQ(41, BindOnce(c2, 13).Run());
[email protected]b38d3572011-02-15 01:27:38447}
448
[email protected]7296f2762011-11-21 19:23:44449// IgnoreResult adapter test.
450// - Function with return value.
451// - Method with return value.
452// - Const Method with return.
453// - Method with return value bound to WeakPtr<>.
454// - Const Method with return bound to WeakPtr<>.
tzikb9499fd92016-10-12 04:55:02455TEST_F(BindTest, IgnoreResultForRepeating) {
[email protected]e8bfc31d2011-09-28 00:26:37456 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
[email protected]7296f2762011-11-21 19:23:44457 EXPECT_CALL(has_ref_, AddRef()).Times(2);
458 EXPECT_CALL(has_ref_, Release()).Times(2);
tzikefea4f52018-08-02 15:20:46459 EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
[email protected]7296f2762011-11-21 19:23:44460 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
461 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
462 EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
463 EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
464
tzikb9499fd92016-10-12 04:55:02465 RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
[email protected]7296f2762011-11-21 19:23:44466 normal_func_cb.Run();
467
tzikb9499fd92016-10-12 04:55:02468 RepeatingClosure non_void_method_cb =
469 BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
[email protected]7296f2762011-11-21 19:23:44470 non_void_method_cb.Run();
471
tzikb9499fd92016-10-12 04:55:02472 RepeatingClosure non_void_const_method_cb =
473 BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
[email protected]7296f2762011-11-21 19:23:44474 non_void_const_method_cb.Run();
475
476 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
Keishi Hattori0e45c022021-11-27 09:25:52477 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
[email protected]7296f2762011-11-21 19:23:44478
Daniel Cheng91f6fbaf2022-09-16 12:07:48479 RepeatingClosure non_void_weak_method_cb = BindRepeating(
480 IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
[email protected]7296f2762011-11-21 19:23:44481 non_void_weak_method_cb.Run();
482
Daniel Cheng91f6fbaf2022-09-16 12:07:48483 RepeatingClosure non_void_weak_const_method_cb = BindRepeating(
484 IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
[email protected]7296f2762011-11-21 19:23:44485 non_void_weak_const_method_cb.Run();
486
487 weak_factory.InvalidateWeakPtrs();
488 non_void_weak_const_method_cb.Run();
489 non_void_weak_method_cb.Run();
[email protected]e8bfc31d2011-09-28 00:26:37490}
491
tzikb9499fd92016-10-12 04:55:02492TEST_F(BindTest, IgnoreResultForOnce) {
493 EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
494 EXPECT_CALL(has_ref_, AddRef()).Times(2);
495 EXPECT_CALL(has_ref_, Release()).Times(2);
tzikefea4f52018-08-02 15:20:46496 EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
tzikb9499fd92016-10-12 04:55:02497 EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
498 EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
[email protected]b38d3572011-02-15 01:27:38499
tzikb9499fd92016-10-12 04:55:02500 OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
501 std::move(normal_func_cb).Run();
[email protected]b38d3572011-02-15 01:27:38502
tzikb9499fd92016-10-12 04:55:02503 OnceClosure non_void_method_cb =
504 BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
505 std::move(non_void_method_cb).Run();
[email protected]b38d3572011-02-15 01:27:38506
tzikb9499fd92016-10-12 04:55:02507 OnceClosure non_void_const_method_cb =
508 BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
509 std::move(non_void_const_method_cb).Run();
[email protected]b38d3572011-02-15 01:27:38510
tzikb9499fd92016-10-12 04:55:02511 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
Keishi Hattori0e45c022021-11-27 09:25:52512 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
[email protected]b38d3572011-02-15 01:27:38513
Daniel Cheng91f6fbaf2022-09-16 12:07:48514 OnceClosure non_void_weak_method_cb =
515 BindOnce(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
516 OnceClosure non_void_weak_const_method_cb = BindOnce(
517 IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
[email protected]b38d3572011-02-15 01:27:38518
tzikb9499fd92016-10-12 04:55:02519 weak_factory.InvalidateWeakPtrs();
520 std::move(non_void_weak_const_method_cb).Run();
521 std::move(non_void_weak_method_cb).Run();
[email protected]c18b1052011-03-24 02:02:17522}
523
danakj779e8302020-10-27 18:35:58524TEST_F(BindTest, IgnoreResultForRepeatingCallback) {
525 std::string s;
526 RepeatingCallback<int(int)> cb = BindRepeating(
527 [](std::string* s, int i) {
Peter Kasting8e4901d2024-02-16 16:34:05528 *s += "Run" + NumberToString(i);
danakj779e8302020-10-27 18:35:58529 return 5;
530 },
531 &s);
532 RepeatingCallback<void(int)> noreturn = BindRepeating(IgnoreResult(cb));
533 noreturn.Run(2);
534 EXPECT_EQ(s, "Run2");
535}
536
537TEST_F(BindTest, IgnoreResultForOnceCallback) {
538 std::string s;
539 OnceCallback<int(int)> cb = BindOnce(
540 [](std::string* s, int i) {
Peter Kasting8e4901d2024-02-16 16:34:05541 *s += "Run" + NumberToString(i);
danakj779e8302020-10-27 18:35:58542 return 5;
543 },
544 &s);
545 OnceCallback<void(int)> noreturn = BindOnce(IgnoreResult(std::move(cb)));
546 std::move(noreturn).Run(2);
547 EXPECT_EQ(s, "Run2");
548}
549
kylechar72e6f782021-03-17 17:43:38550void SetFromRef(int& ref) {
551 EXPECT_EQ(ref, 1);
552 ref = 2;
553 EXPECT_EQ(ref, 2);
554}
555
556TEST_F(BindTest, BindOnceWithNonConstRef) {
557 int v = 1;
558
559 // Mutates `v` because it's not bound to callback instead it's forwarded by
560 // Run().
561 auto cb1 = BindOnce(SetFromRef);
562 std::move(cb1).Run(v);
563 EXPECT_EQ(v, 2);
564 v = 1;
565
566 // Mutates `v` through std::reference_wrapper bound to callback.
567 auto cb2 = BindOnce(SetFromRef, std::ref(v));
568 std::move(cb2).Run();
569 EXPECT_EQ(v, 2);
570 v = 1;
571
572 // Everything past here following will make a copy of the argument. The copy
573 // will be mutated and leave `v` unmodified.
Peter Kasting8e4901d2024-02-16 16:34:05574 auto cb3 = BindOnce(SetFromRef, OwnedRef(v));
kylechar72e6f782021-03-17 17:43:38575 std::move(cb3).Run();
576 EXPECT_EQ(v, 1);
577
578 int& ref = v;
Peter Kasting8e4901d2024-02-16 16:34:05579 auto cb4 = BindOnce(SetFromRef, OwnedRef(ref));
kylechar72e6f782021-03-17 17:43:38580 std::move(cb4).Run();
581 EXPECT_EQ(v, 1);
582
583 const int cv = 1;
Peter Kasting8e4901d2024-02-16 16:34:05584 auto cb5 = BindOnce(SetFromRef, OwnedRef(cv));
kylechar72e6f782021-03-17 17:43:38585 std::move(cb5).Run();
586 EXPECT_EQ(cv, 1);
587
588 const int& cref = v;
Peter Kasting8e4901d2024-02-16 16:34:05589 auto cb6 = BindOnce(SetFromRef, OwnedRef(cref));
kylechar72e6f782021-03-17 17:43:38590 std::move(cb6).Run();
591 EXPECT_EQ(cref, 1);
592
Peter Kasting8e4901d2024-02-16 16:34:05593 auto cb7 = BindOnce(SetFromRef, OwnedRef(1));
kylechar72e6f782021-03-17 17:43:38594 std::move(cb7).Run();
595}
596
597TEST_F(BindTest, BindRepeatingWithNonConstRef) {
598 int v = 1;
599
600 // Mutates `v` because it's not bound to callback instead it's forwarded by
601 // Run().
602 auto cb1 = BindRepeating(SetFromRef);
603 std::move(cb1).Run(v);
604 EXPECT_EQ(v, 2);
605 v = 1;
606
607 // Mutates `v` through std::reference_wrapper bound to callback.
608 auto cb2 = BindRepeating(SetFromRef, std::ref(v));
609 std::move(cb2).Run();
610 EXPECT_EQ(v, 2);
611 v = 1;
612
613 // Everything past here following will make a copy of the argument. The copy
614 // will be mutated and leave `v` unmodified.
Peter Kasting8e4901d2024-02-16 16:34:05615 auto cb3 = BindRepeating(SetFromRef, OwnedRef(v));
kylechar72e6f782021-03-17 17:43:38616 std::move(cb3).Run();
617 EXPECT_EQ(v, 1);
618
619 int& ref = v;
Peter Kasting8e4901d2024-02-16 16:34:05620 auto cb4 = BindRepeating(SetFromRef, OwnedRef(ref));
kylechar72e6f782021-03-17 17:43:38621 std::move(cb4).Run();
622 EXPECT_EQ(v, 1);
623
624 const int cv = 1;
Peter Kasting8e4901d2024-02-16 16:34:05625 auto cb5 = BindRepeating(SetFromRef, OwnedRef(cv));
kylechar72e6f782021-03-17 17:43:38626 std::move(cb5).Run();
627 EXPECT_EQ(cv, 1);
628
629 const int& cref = v;
Peter Kasting8e4901d2024-02-16 16:34:05630 auto cb6 = BindRepeating(SetFromRef, OwnedRef(cref));
kylechar72e6f782021-03-17 17:43:38631 std::move(cb6).Run();
632 EXPECT_EQ(cref, 1);
633
Peter Kasting8e4901d2024-02-16 16:34:05634 auto cb7 = BindRepeating(SetFromRef, OwnedRef(1));
kylechar72e6f782021-03-17 17:43:38635 std::move(cb7).Run();
636}
637
[email protected]b38d3572011-02-15 01:27:38638// Functions that take reference parameters.
639// - Forced reference parameter type still stores a copy.
640// - Forced const reference parameter type still stores a copy.
tzikb9499fd92016-10-12 04:55:02641TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
[email protected]b38d3572011-02-15 01:27:38642 int n = 1;
643 int& ref_n = n;
644 const int& const_ref_n = n;
645
tzikb9499fd92016-10-12 04:55:02646 RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
[email protected]b38d3572011-02-15 01:27:38647 EXPECT_EQ(n, ref_copies_cb.Run());
648 n++;
649 EXPECT_EQ(n - 1, ref_copies_cb.Run());
650
tzikb9499fd92016-10-12 04:55:02651 RepeatingCallback<int()> const_ref_copies_cb =
652 BindRepeating(&Identity, const_ref_n);
[email protected]b38d3572011-02-15 01:27:38653 EXPECT_EQ(n, const_ref_copies_cb.Run());
654 n++;
655 EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
656}
657
tzikb9499fd92016-10-12 04:55:02658TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
659 int n = 1;
660 int& ref_n = n;
661 const int& const_ref_n = n;
662
663 OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
664 n++;
665 EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
666
Daniel Cheng91f6fbaf2022-09-16 12:07:48667 OnceCallback<int()> const_ref_copies_cb = BindOnce(&Identity, const_ref_n);
tzikb9499fd92016-10-12 04:55:02668 n++;
669 EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
670}
671
[email protected]b38d3572011-02-15 01:27:38672// Check that we can pass in arrays and have them be stored as a pointer.
673// - Array of values stores a pointer.
674// - Array of const values stores a pointer.
tzikb9499fd92016-10-12 04:55:02675TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
[email protected]b38d3572011-02-15 01:27:38676 int array[4] = {1, 1, 1, 1};
Daniel Cheng91f6fbaf2022-09-16 12:07:48677 const int(*const_array_ptr)[4] = &array;
[email protected]b38d3572011-02-15 01:27:38678
tzikb9499fd92016-10-12 04:55:02679 RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
[email protected]b38d3572011-02-15 01:27:38680 EXPECT_EQ(1, array_cb.Run());
681
tzikb9499fd92016-10-12 04:55:02682 RepeatingCallback<int()> const_array_cb =
683 BindRepeating(&ArrayGet, *const_array_ptr, 1);
[email protected]b38d3572011-02-15 01:27:38684 EXPECT_EQ(1, const_array_cb.Run());
685
686 array[1] = 3;
687 EXPECT_EQ(3, array_cb.Run());
688 EXPECT_EQ(3, const_array_cb.Run());
689}
690
tzikb9499fd92016-10-12 04:55:02691TEST_F(BindTest, ArrayArgumentBindingForOnce) {
692 int array[4] = {1, 1, 1, 1};
Daniel Cheng91f6fbaf2022-09-16 12:07:48693 const int(*const_array_ptr)[4] = &array;
[email protected]b38d3572011-02-15 01:27:38694
tzikb9499fd92016-10-12 04:55:02695 OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
Daniel Cheng91f6fbaf2022-09-16 12:07:48696 OnceCallback<int()> const_array_cb = BindOnce(&ArrayGet, *const_array_ptr, 1);
[email protected]b38d3572011-02-15 01:27:38697
tzikb9499fd92016-10-12 04:55:02698 array[1] = 3;
699 EXPECT_EQ(3, std::move(array_cb).Run());
700 EXPECT_EQ(3, std::move(const_array_cb).Run());
[email protected]b38d3572011-02-15 01:27:38701}
702
[email protected]93540582011-05-16 22:35:14703// WeakPtr() support.
704// - Method bound to WeakPtr<> to non-const object.
705// - Const method bound to WeakPtr<> to non-const object.
706// - Const method bound to WeakPtr<> to const object.
707// - Normal Function with WeakPtr<> as P1 can have return type and is
708// not canceled.
tzikb9499fd92016-10-12 04:55:02709TEST_F(BindTest, WeakPtrForRepeating) {
[email protected]93540582011-05-16 22:35:14710 EXPECT_CALL(no_ref_, VoidMethod0());
711 EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
712
713 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
Keishi Hattori0e45c022021-11-27 09:25:52714 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
[email protected]93540582011-05-16 22:35:14715
tzikb9499fd92016-10-12 04:55:02716 RepeatingClosure method_cb =
717 BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14718 method_cb.Run();
719
tzikb9499fd92016-10-12 04:55:02720 RepeatingClosure const_method_cb =
721 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14722 const_method_cb.Run();
723
tzikb9499fd92016-10-12 04:55:02724 RepeatingClosure const_method_const_ptr_cb =
725 BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14726 const_method_const_ptr_cb.Run();
727
tzikb9499fd92016-10-12 04:55:02728 RepeatingCallback<int(int)> normal_func_cb =
729 BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
[email protected]93540582011-05-16 22:35:14730 EXPECT_EQ(1, normal_func_cb.Run(1));
731
732 weak_factory.InvalidateWeakPtrs();
733 const_weak_factory.InvalidateWeakPtrs();
734
735 method_cb.Run();
736 const_method_cb.Run();
737 const_method_const_ptr_cb.Run();
738
739 // Still runs even after the pointers are invalidated.
740 EXPECT_EQ(2, normal_func_cb.Run(2));
741}
742
tzikb9499fd92016-10-12 04:55:02743TEST_F(BindTest, WeakPtrForOnce) {
744 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
Keishi Hattori0e45c022021-11-27 09:25:52745 WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
tzikb9499fd92016-10-12 04:55:02746
747 OnceClosure method_cb =
748 BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
749 OnceClosure const_method_cb =
750 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
751 OnceClosure const_method_const_ptr_cb =
752 BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
kylechar650caf02019-07-17 03:25:41753 OnceCallback<int(int)> normal_func_cb =
754 BindOnce(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
tzikb9499fd92016-10-12 04:55:02755
756 weak_factory.InvalidateWeakPtrs();
757 const_weak_factory.InvalidateWeakPtrs();
758
759 std::move(method_cb).Run();
760 std::move(const_method_cb).Run();
761 std::move(const_method_const_ptr_cb).Run();
762
763 // Still runs even after the pointers are invalidated.
764 EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
765}
766
jdoerrie9d7236f62019-03-05 13:00:23767// std::cref() wrapper support.
768// - Binding w/o std::cref takes a copy.
769// - Binding a std::cref takes a reference.
770// - Binding std::cref to a function std::cref does not copy on invoke.
771TEST_F(BindTest, StdCrefForRepeating) {
[email protected]b38d3572011-02-15 01:27:38772 int n = 1;
773
tzikb9499fd92016-10-12 04:55:02774 RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
jdoerrie9d7236f62019-03-05 13:00:23775 RepeatingCallback<int()> const_ref_cb =
776 BindRepeating(&Identity, std::cref(n));
[email protected]b38d3572011-02-15 01:27:38777 EXPECT_EQ(n, copy_cb.Run());
778 EXPECT_EQ(n, const_ref_cb.Run());
779 n++;
780 EXPECT_EQ(n - 1, copy_cb.Run());
781 EXPECT_EQ(n, const_ref_cb.Run());
782
783 int copies = 0;
784 int assigns = 0;
tzik52dcd672016-02-15 11:54:30785 int move_constructs = 0;
786 int move_assigns = 0;
787 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
tzikb9499fd92016-10-12 04:55:02788 RepeatingCallback<int()> all_const_ref_cb =
jdoerrie9d7236f62019-03-05 13:00:23789 BindRepeating(&GetCopies, std::cref(counter));
[email protected]b38d3572011-02-15 01:27:38790 EXPECT_EQ(0, all_const_ref_cb.Run());
791 EXPECT_EQ(0, copies);
792 EXPECT_EQ(0, assigns);
tzik52dcd672016-02-15 11:54:30793 EXPECT_EQ(0, move_constructs);
794 EXPECT_EQ(0, move_assigns);
[email protected]b38d3572011-02-15 01:27:38795}
796
jdoerrie9d7236f62019-03-05 13:00:23797TEST_F(BindTest, StdCrefForOnce) {
tzikb9499fd92016-10-12 04:55:02798 int n = 1;
[email protected]edd2f1b2013-06-22 20:32:50799
tzikb9499fd92016-10-12 04:55:02800 OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
jdoerrie9d7236f62019-03-05 13:00:23801 OnceCallback<int()> const_ref_cb = BindOnce(&Identity, std::cref(n));
tzikb9499fd92016-10-12 04:55:02802 n++;
803 EXPECT_EQ(n - 1, std::move(copy_cb).Run());
804 EXPECT_EQ(n, std::move(const_ref_cb).Run());
805
806 int copies = 0;
807 int assigns = 0;
808 int move_constructs = 0;
809 int move_assigns = 0;
810 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
811 OnceCallback<int()> all_const_ref_cb =
jdoerrie9d7236f62019-03-05 13:00:23812 BindOnce(&GetCopies, std::cref(counter));
tzikb9499fd92016-10-12 04:55:02813 EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
814 EXPECT_EQ(0, copies);
815 EXPECT_EQ(0, assigns);
816 EXPECT_EQ(0, move_constructs);
817 EXPECT_EQ(0, move_assigns);
[email protected]edd2f1b2013-06-22 20:32:50818}
819
[email protected]08aa4552011-10-15 00:34:42820// Test Owned() support.
jdoerrie68f2d51b2019-02-28 17:32:44821TEST_F(BindTest, OwnedForRepeatingRawPtr) {
[email protected]08aa4552011-10-15 00:34:42822 int deletes = 0;
823 DeleteCounter* counter = new DeleteCounter(&deletes);
824
825 // If we don't capture, delete happens on Callback destruction/reset.
826 // return the same value.
tzikb9499fd92016-10-12 04:55:02827 RepeatingCallback<DeleteCounter*()> no_capture_cb =
828 BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
[email protected]206a2ae82011-12-22 21:12:58829 ASSERT_EQ(counter, no_capture_cb.Run());
830 ASSERT_EQ(counter, no_capture_cb.Run());
[email protected]08aa4552011-10-15 00:34:42831 EXPECT_EQ(0, deletes);
832 no_capture_cb.Reset(); // This should trigger a delete.
833 EXPECT_EQ(1, deletes);
834
835 deletes = 0;
836 counter = new DeleteCounter(&deletes);
tzikb9499fd92016-10-12 04:55:02837 RepeatingClosure own_object_cb =
838 BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
[email protected]08aa4552011-10-15 00:34:42839 own_object_cb.Run();
840 EXPECT_EQ(0, deletes);
841 own_object_cb.Reset();
842 EXPECT_EQ(1, deletes);
843}
844
jdoerrie68f2d51b2019-02-28 17:32:44845TEST_F(BindTest, OwnedForOnceRawPtr) {
tzikb9499fd92016-10-12 04:55:02846 int deletes = 0;
847 DeleteCounter* counter = new DeleteCounter(&deletes);
848
849 // If we don't capture, delete happens on Callback destruction/reset.
850 // return the same value.
851 OnceCallback<DeleteCounter*()> no_capture_cb =
852 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
853 EXPECT_EQ(0, deletes);
854 no_capture_cb.Reset(); // This should trigger a delete.
855 EXPECT_EQ(1, deletes);
856
857 deletes = 0;
858 counter = new DeleteCounter(&deletes);
859 OnceClosure own_object_cb =
860 BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
861 EXPECT_EQ(0, deletes);
862 own_object_cb.Reset();
863 EXPECT_EQ(1, deletes);
864}
865
jdoerrie68f2d51b2019-02-28 17:32:44866TEST_F(BindTest, OwnedForRepeatingUniquePtr) {
867 int deletes = 0;
868 auto counter = std::make_unique<DeleteCounter>(&deletes);
869 DeleteCounter* raw_counter = counter.get();
870
871 // If we don't capture, delete happens on Callback destruction/reset.
872 // return the same value.
873 RepeatingCallback<DeleteCounter*()> no_capture_cb = BindRepeating(
874 &PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
875 ASSERT_EQ(raw_counter, no_capture_cb.Run());
876 ASSERT_EQ(raw_counter, no_capture_cb.Run());
877 EXPECT_EQ(0, deletes);
878 no_capture_cb.Reset(); // This should trigger a delete.
879 EXPECT_EQ(1, deletes);
880
881 deletes = 0;
882 counter = std::make_unique<DeleteCounter>(&deletes);
883 RepeatingClosure own_object_cb =
884 BindRepeating(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
885 own_object_cb.Run();
886 EXPECT_EQ(0, deletes);
887 own_object_cb.Reset();
888 EXPECT_EQ(1, deletes);
889}
890
891TEST_F(BindTest, OwnedForOnceUniquePtr) {
892 int deletes = 0;
893 auto counter = std::make_unique<DeleteCounter>(&deletes);
894
895 // If we don't capture, delete happens on Callback destruction/reset.
896 // return the same value.
897 OnceCallback<DeleteCounter*()> no_capture_cb =
898 BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
899 EXPECT_EQ(0, deletes);
900 no_capture_cb.Reset(); // This should trigger a delete.
901 EXPECT_EQ(1, deletes);
902
903 deletes = 0;
904 counter = std::make_unique<DeleteCounter>(&deletes);
905 OnceClosure own_object_cb =
906 BindOnce(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
907 EXPECT_EQ(0, deletes);
908 own_object_cb.Reset();
909 EXPECT_EQ(1, deletes);
910}
911
Jan Wilken Dörrie1d011fb2021-03-11 19:37:37912// Tests OwnedRef
913TEST_F(BindTest, OwnedRefForCounter) {
914 int counter = 0;
915 RepeatingCallback<int()> counter_callback =
916 BindRepeating([](int& counter) { return ++counter; }, OwnedRef(counter));
917
918 EXPECT_EQ(1, counter_callback.Run());
919 EXPECT_EQ(2, counter_callback.Run());
920 EXPECT_EQ(3, counter_callback.Run());
921 EXPECT_EQ(4, counter_callback.Run());
922
923 EXPECT_EQ(0, counter); // counter should remain unchanged.
924}
925
926TEST_F(BindTest, OwnedRefForIgnoringArguments) {
927 OnceCallback<std::string(std::string)> echo_callback =
928 BindOnce([](int& ignore, std::string s) { return s; }, OwnedRef(0));
929
930 EXPECT_EQ("Hello World", std::move(echo_callback).Run("Hello World"));
931}
932
tzikb9499fd92016-10-12 04:55:02933template <typename T>
Daniel Cheng91f6fbaf2022-09-16 12:07:48934class BindVariantsTest : public ::testing::Test {};
tzikb9499fd92016-10-12 04:55:02935
936struct RepeatingTestConfig {
937 template <typename Signature>
938 using CallbackType = RepeatingCallback<Signature>;
939 using ClosureType = RepeatingClosure;
940
941 template <typename F, typename... Args>
Peter Kasting52d553c132023-12-11 22:43:48942 static auto Bind(F&& f, Args&&... args) {
tzikb9499fd92016-10-12 04:55:02943 return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
944 }
945};
946
947struct OnceTestConfig {
948 template <typename Signature>
949 using CallbackType = OnceCallback<Signature>;
950 using ClosureType = OnceClosure;
951
952 template <typename F, typename... Args>
Peter Kasting52d553c132023-12-11 22:43:48953 static auto Bind(F&& f, Args&&... args) {
tzikb9499fd92016-10-12 04:55:02954 return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
955 }
956};
957
Daniel Cheng91f6fbaf2022-09-16 12:07:48958using BindVariantsTestConfig =
959 ::testing::Types<RepeatingTestConfig, OnceTestConfig>;
Victor Costanebc52732019-02-15 02:39:47960TYPED_TEST_SUITE(BindVariantsTest, BindVariantsTestConfig);
tzikb9499fd92016-10-12 04:55:02961
962template <typename TypeParam, typename Signature>
963using CallbackType = typename TypeParam::template CallbackType<Signature>;
964
965// Function type support.
966// - Normal function.
967// - Normal function bound with non-refcounted first argument.
968// - Method bound to non-const object.
969// - Method bound to scoped_refptr.
970// - Const method bound to non-const object.
971// - Const method bound to const object.
972// - Derived classes can be used with pointers to non-virtual base functions.
973// - Derived classes can be used with pointers to virtual base functions (and
974// preserve virtual dispatch).
975TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
976 using ClosureType = typename TypeParam::ClosureType;
977
978 StrictMock<HasRef> has_ref;
979 StrictMock<NoRef> no_ref;
980 StrictMock<NoRef> static_func_mock;
981 const HasRef* const_has_ref_ptr = &has_ref;
982 g_func_mock_ptr = &static_func_mock;
983
984 EXPECT_CALL(static_func_mock, VoidMethod0());
985 EXPECT_CALL(has_ref, AddRef()).Times(4);
986 EXPECT_CALL(has_ref, Release()).Times(4);
tzikefea4f52018-08-02 15:20:46987 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
tzikb9499fd92016-10-12 04:55:02988 EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
989 EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
990
991 ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
992 CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
993 TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
994 std::move(normal_cb).Run();
995 EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
996
997 ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
kylechar973a0412017-09-26 18:40:29998 ClosureType method_refptr_cb =
999 TypeParam::Bind(&HasRef::VoidMethod0, WrapRefCounted(&has_ref));
tzikb9499fd92016-10-12 04:55:021000 ClosureType const_method_nonconst_obj_cb =
1001 TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
1002 ClosureType const_method_const_obj_cb =
1003 TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
1004 std::move(method_cb).Run();
1005 std::move(method_refptr_cb).Run();
1006 std::move(const_method_nonconst_obj_cb).Run();
1007 std::move(const_method_const_obj_cb).Run();
1008
1009 Child child;
1010 child.value = 0;
1011 ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
1012 std::move(virtual_set_cb).Run();
1013 EXPECT_EQ(kChildValue, child.value);
1014
1015 child.value = 0;
1016 ClosureType non_virtual_set_cb =
1017 TypeParam::Bind(&Parent::NonVirtualSet, &child);
1018 std::move(non_virtual_set_cb).Run();
1019 EXPECT_EQ(kParentValue, child.value);
1020}
1021
1022// Return value support.
1023// - Function with return value.
1024// - Method with return value.
1025// - Const method with return value.
1026// - Move-only return value.
1027TYPED_TEST(BindVariantsTest, ReturnValues) {
1028 StrictMock<NoRef> static_func_mock;
1029 StrictMock<HasRef> has_ref;
1030 g_func_mock_ptr = &static_func_mock;
1031 const HasRef* const_has_ref_ptr = &has_ref;
1032
1033 EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
1034 EXPECT_CALL(has_ref, AddRef()).Times(4);
1035 EXPECT_CALL(has_ref, Release()).Times(4);
tzikefea4f52018-08-02 15:20:461036 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
tzikb9499fd92016-10-12 04:55:021037 EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
1038 EXPECT_CALL(has_ref, IntConstMethod0())
1039 .WillOnce(Return(41337))
1040 .WillOnce(Return(51337));
1041 EXPECT_CALL(has_ref, UniquePtrMethod0())
Jeremy Roman9532f252017-08-16 23:27:241042 .WillOnce(Return(ByMove(std::make_unique<int>(42))));
tzikb9499fd92016-10-12 04:55:021043
1044 CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
1045 CallbackType<TypeParam, int()> method_cb =
1046 TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
1047 CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
1048 TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
1049 CallbackType<TypeParam, int()> const_method_const_obj_cb =
1050 TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
1051 CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
1052 TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
1053 EXPECT_EQ(1337, std::move(normal_cb).Run());
1054 EXPECT_EQ(31337, std::move(method_cb).Run());
1055 EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
1056 EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
1057 EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
1058}
1059
1060// Argument binding tests.
1061// - Argument binding to primitive.
1062// - Argument binding to primitive pointer.
1063// - Argument binding to a literal integer.
1064// - Argument binding to a literal string.
1065// - Argument binding with template function.
1066// - Argument binding to an object.
1067// - Argument binding to pointer to incomplete type.
1068// - Argument gets type converted.
1069// - Pointer argument gets converted.
1070// - Const Reference forces conversion.
1071TYPED_TEST(BindVariantsTest, ArgumentBinding) {
1072 int n = 2;
1073
1074 EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
1075 EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
1076 EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
1077 EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
1078 EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
1079
1080 NoRefParent p;
1081 p.value = 5;
1082 EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
1083
tzikb9499fd92016-10-12 04:55:021084 NoRefChild c;
1085 c.value = 6;
1086 EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
1087
1088 c.value = 7;
1089 EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
1090
1091 c.value = 8;
1092 EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
1093}
1094
1095// Unbound argument type support tests.
1096// - Unbound value.
1097// - Unbound pointer.
1098// - Unbound reference.
1099// - Unbound const reference.
1100// - Unbound unsized array.
1101// - Unbound sized array.
1102// - Unbound array-of-arrays.
1103TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
1104 CallbackType<TypeParam, void(int)> unbound_value_cb =
1105 TypeParam::Bind(&VoidPolymorphic<int>::Run);
1106 CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
1107 TypeParam::Bind(&VoidPolymorphic<int*>::Run);
1108 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
1109 TypeParam::Bind(&VoidPolymorphic<int&>::Run);
1110 CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
1111 TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
1112 CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
1113 TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
1114 CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
1115 TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
1116 CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
1117 TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
1118 CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
1119 TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
1120}
1121
1122// Function with unbound reference parameter.
1123// - Original parameter is modified by callback.
1124TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
1125 int n = 0;
1126 CallbackType<TypeParam, void(int&)> unbound_ref_cb =
1127 TypeParam::Bind(&RefArgSet);
1128 std::move(unbound_ref_cb).Run(n);
1129 EXPECT_EQ(2, n);
1130}
1131
1132// Unretained() wrapper support.
1133// - Method bound to Unretained() non-const object.
1134// - Const method bound to Unretained() non-const object.
1135// - Const method bound to Unretained() const object.
1136TYPED_TEST(BindVariantsTest, Unretained) {
1137 StrictMock<NoRef> no_ref;
1138 const NoRef* const_no_ref_ptr = &no_ref;
1139
1140 EXPECT_CALL(no_ref, VoidMethod0());
1141 EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
1142
1143 TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
1144 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
1145 TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
1146}
1147
1148TYPED_TEST(BindVariantsTest, ScopedRefptr) {
1149 StrictMock<HasRef> has_ref;
1150 EXPECT_CALL(has_ref, AddRef()).Times(1);
1151 EXPECT_CALL(has_ref, Release()).Times(1);
tzikefea4f52018-08-02 15:20:461152 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
tzikb9499fd92016-10-12 04:55:021153
1154 const scoped_refptr<HasRef> refptr(&has_ref);
jdoerrie9d7236f62019-03-05 13:00:231155 CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb = TypeParam::Bind(
1156 &FunctionWithScopedRefptrFirstParam, std::cref(refptr), 1);
tzikb9499fd92016-10-12 04:55:021157 EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
1158}
1159
1160TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
Charles Meng300bcec72025-11-10 19:13:491161 auto no_ref = std::make_unique<StrictMock<NoRef>>();
tzik4435e8042016-05-11 23:05:051162 EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
tzikb9499fd92016-10-12 04:55:021163 TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
tzik4435e8042016-05-11 23:05:051164}
1165
Daniel Cheng00c072a2022-06-11 18:50:371166TYPED_TEST(BindVariantsTest, ImplicitRefPtrReceiver) {
1167 StrictMock<HasRef> has_ref;
1168 EXPECT_CALL(has_ref, AddRef()).Times(1);
1169 EXPECT_CALL(has_ref, Release()).Times(1);
1170 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1171
1172 HasRef* ptr = &has_ref;
1173 auto ptr_cb = TypeParam::Bind(&HasRef::HasAtLeastOneRef, ptr);
1174 EXPECT_EQ(1, std::move(ptr_cb).Run());
1175}
1176
1177TYPED_TEST(BindVariantsTest, RawPtrReceiver) {
1178 StrictMock<HasRef> has_ref;
1179 EXPECT_CALL(has_ref, AddRef()).Times(1);
1180 EXPECT_CALL(has_ref, Release()).Times(1);
1181 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1182
1183 raw_ptr<HasRef> rawptr(&has_ref);
1184 auto rawptr_cb = TypeParam::Bind(&HasRef::HasAtLeastOneRef, rawptr);
1185 EXPECT_EQ(1, std::move(rawptr_cb).Run());
1186}
1187
danakj92061c12022-07-28 23:53:501188TYPED_TEST(BindVariantsTest, UnretainedRawRefReceiver) {
1189 StrictMock<HasRef> has_ref;
1190 EXPECT_CALL(has_ref, AddRef()).Times(0);
1191 EXPECT_CALL(has_ref, Release()).Times(0);
1192 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1193
1194 raw_ref<HasRef> raw_has_ref(has_ref);
1195 auto has_ref_cb =
1196 TypeParam::Bind(&HasRef::HasAtLeastOneRef, Unretained(raw_has_ref));
1197 EXPECT_EQ(1, std::move(has_ref_cb).Run());
1198
1199 StrictMock<NoRef> no_ref;
1200 EXPECT_CALL(has_ref, IntMethod0()).WillRepeatedly(Return(1));
1201
1202 raw_ref<NoRef> raw_no_ref(has_ref);
1203 auto no_ref_cb = TypeParam::Bind(&NoRef::IntMethod0, Unretained(raw_no_ref));
1204 EXPECT_EQ(1, std::move(no_ref_cb).Run());
1205}
1206
dchengf10b7732016-01-21 19:37:551207// Tests for Passed() wrapper support:
[email protected]206a2ae82011-12-22 21:12:581208// - Passed() can be constructed from a pointer to scoper.
1209// - Passed() can be constructed from a scoper rvalue.
1210// - Using Passed() gives Callback Ownership.
1211// - Ownership is transferred from Callback to callee on the first Run().
1212// - Callback supports unbound arguments.
dchengf10b7732016-01-21 19:37:551213template <typename T>
Daniel Cheng91f6fbaf2022-09-16 12:07:481214class BindMoveOnlyTypeTest : public ::testing::Test {};
dchengf10b7732016-01-21 19:37:551215
1216struct CustomDeleter {
1217 void operator()(DeleteCounter* c) { delete c; }
1218};
1219
1220using MoveOnlyTypesToTest =
dcheng093de9b2016-04-04 21:25:511221 ::testing::Types<std::unique_ptr<DeleteCounter>,
dchengf10b7732016-01-21 19:37:551222 std::unique_ptr<DeleteCounter, CustomDeleter>>;
Victor Costanebc52732019-02-15 02:39:471223TYPED_TEST_SUITE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
dchengf10b7732016-01-21 19:37:551224
1225TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
[email protected]206a2ae82011-12-22 21:12:581226 int deletes = 0;
1227
dchengf10b7732016-01-21 19:37:551228 TypeParam ptr(new DeleteCounter(&deletes));
kylechar650caf02019-07-17 03:25:411229 RepeatingCallback<TypeParam()> callback =
1230 BindRepeating(&PassThru<TypeParam>, Passed(&ptr));
[email protected]206a2ae82011-12-22 21:12:581231 EXPECT_FALSE(ptr.get());
1232 EXPECT_EQ(0, deletes);
1233
1234 // If we never invoke the Callback, it retains ownership and deletes.
[email protected]206a2ae82011-12-22 21:12:581235 callback.Reset();
[email protected]206a2ae82011-12-22 21:12:581236 EXPECT_EQ(1, deletes);
[email protected]206a2ae82011-12-22 21:12:581237}
1238
dchengf10b7732016-01-21 19:37:551239TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
dcheng69f2a042015-12-14 20:31:521240 int deletes = 0;
kylechar650caf02019-07-17 03:25:411241 RepeatingCallback<TypeParam()> callback = BindRepeating(
dchengf10b7732016-01-21 19:37:551242 &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
dcheng69f2a042015-12-14 20:31:521243 EXPECT_EQ(0, deletes);
1244
1245 // If we never invoke the Callback, it retains ownership and deletes.
dchengf10b7732016-01-21 19:37:551246 callback.Reset();
dcheng69f2a042015-12-14 20:31:521247 EXPECT_EQ(1, deletes);
dchengf10b7732016-01-21 19:37:551248}
dcheng69f2a042015-12-14 20:31:521249
dchengf10b7732016-01-21 19:37:551250// Check that ownership can be transferred back out.
1251TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
1252 int deletes = 0;
dcheng69f2a042015-12-14 20:31:521253 DeleteCounter* counter = new DeleteCounter(&deletes);
kylechar650caf02019-07-17 03:25:411254 RepeatingCallback<TypeParam()> callback =
1255 BindRepeating(&PassThru<TypeParam>, Passed(TypeParam(counter)));
dchengf10b7732016-01-21 19:37:551256 TypeParam result = callback.Run();
dcheng69f2a042015-12-14 20:31:521257 ASSERT_EQ(counter, result.get());
1258 EXPECT_EQ(0, deletes);
1259
1260 // Resetting does not delete since ownership was transferred.
1261 callback.Reset();
1262 EXPECT_EQ(0, deletes);
1263
1264 // Ensure that we actually did get ownership.
1265 result.reset();
1266 EXPECT_EQ(1, deletes);
dchengf10b7732016-01-21 19:37:551267}
dcheng69f2a042015-12-14 20:31:521268
dchengf10b7732016-01-21 19:37:551269TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
1270 int deletes = 0;
1271 TypeParam ptr(new DeleteCounter(&deletes));
dcheng69f2a042015-12-14 20:31:521272 // Test unbound argument forwarding.
kylechar650caf02019-07-17 03:25:411273 RepeatingCallback<TypeParam(TypeParam)> cb_unbound =
1274 BindRepeating(&PassThru<TypeParam>);
dcheng69f2a042015-12-14 20:31:521275 cb_unbound.Run(std::move(ptr));
dchengf10b7732016-01-21 19:37:551276 EXPECT_EQ(1, deletes);
dcheng69f2a042015-12-14 20:31:521277}
1278
dcheng093de9b2016-04-04 21:25:511279void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
dcheng53b4cea2016-02-02 04:09:331280 ASSERT_EQ(1u, v.size());
1281 EXPECT_EQ(12345, *v[0]);
1282}
1283
dcheng093de9b2016-04-04 21:25:511284std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
1285 std::vector<std::unique_ptr<int>> v) {
dcheng53b4cea2016-02-02 04:09:331286 VerifyVector(v);
1287 return v;
1288}
1289
1290// Test that a vector containing move-only types can be used with Callback.
1291TEST_F(BindTest, BindMoveOnlyVector) {
dcheng093de9b2016-04-04 21:25:511292 using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
dcheng53b4cea2016-02-02 04:09:331293
1294 MoveOnlyVector v;
David Benjamindd436292018-10-11 16:28:001295 v.push_back(std::make_unique<int>(12345));
dcheng53b4cea2016-02-02 04:09:331296
1297 // Early binding should work:
Peter Kasting8e4901d2024-02-16 16:34:051298 RepeatingCallback<MoveOnlyVector()> bound_cb =
1299 BindRepeating(&AcceptAndReturnMoveOnlyVector, Passed(&v));
dcheng53b4cea2016-02-02 04:09:331300 MoveOnlyVector intermediate_result = bound_cb.Run();
1301 VerifyVector(intermediate_result);
1302
1303 // As should passing it as an argument to Run():
Peter Kasting8e4901d2024-02-16 16:34:051304 RepeatingCallback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
1305 BindRepeating(&AcceptAndReturnMoveOnlyVector);
dcheng53b4cea2016-02-02 04:09:331306 MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
1307 VerifyVector(final_result);
1308}
1309
Peter Kastingf818a6f2024-02-21 18:21:281310// Using Passed() on a functor should not cause a compile error.
1311TEST_F(BindTest, PassedFunctor) {
1312 struct S {
1313 void operator()() const {}
1314 };
1315
1316 BindRepeating(Passed(S())).Run();
1317}
1318
tzik52dcd672016-02-15 11:54:301319// Argument copy-constructor usage for non-reference copy-only parameters.
[email protected]b38d3572011-02-15 01:27:381320// - Bound arguments are only copied once.
1321// - Forwarded arguments are only copied once.
[email protected]206a2ae82011-12-22 21:12:581322// - Forwarded arguments with coercions are only copied twice (once for the
1323// coercion, and one for the final dispatch).
[email protected]b38d3572011-02-15 01:27:381324TEST_F(BindTest, ArgumentCopies) {
1325 int copies = 0;
1326 int assigns = 0;
1327
1328 CopyCounter counter(&copies, &assigns);
Colin Blundell6cc94b52021-05-05 11:13:381329 BindRepeating(&VoidPolymorphic<CopyCounter>::Run, counter);
tzik52dcd672016-02-15 11:54:301330 EXPECT_EQ(1, copies);
[email protected]b38d3572011-02-15 01:27:381331 EXPECT_EQ(0, assigns);
1332
1333 copies = 0;
1334 assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381335 BindRepeating(&VoidPolymorphic<CopyCounter>::Run,
1336 CopyCounter(&copies, &assigns));
tzik52dcd672016-02-15 11:54:301337 EXPECT_EQ(1, copies);
[email protected]b38d3572011-02-15 01:27:381338 EXPECT_EQ(0, assigns);
1339
1340 copies = 0;
1341 assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381342 BindRepeating(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
tzika43eff02016-03-09 05:46:051343 EXPECT_EQ(2, copies);
[email protected]b38d3572011-02-15 01:27:381344 EXPECT_EQ(0, assigns);
tzik52dcd672016-02-15 11:54:301345
1346 copies = 0;
1347 assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381348 BindRepeating(&VoidPolymorphic<CopyCounter>::Run)
1349 .Run(CopyCounter(&copies, &assigns));
tzik52dcd672016-02-15 11:54:301350 EXPECT_EQ(1, copies);
1351 EXPECT_EQ(0, assigns);
1352
1353 copies = 0;
1354 assigns = 0;
1355 DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
Colin Blundell6cc94b52021-05-05 11:13:381356 BindRepeating(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
tzik52dcd672016-02-15 11:54:301357 EXPECT_EQ(2, copies);
1358 EXPECT_EQ(0, assigns);
1359
1360 copies = 0;
1361 assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381362 BindRepeating(&VoidPolymorphic<CopyCounter>::Run)
tzik52dcd672016-02-15 11:54:301363 .Run(CopyCounter(
1364 DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
1365 EXPECT_EQ(2, copies);
1366 EXPECT_EQ(0, assigns);
1367}
1368
1369// Argument move-constructor usage for move-only parameters.
1370// - Bound arguments passed by move are not copied.
1371TEST_F(BindTest, ArgumentMoves) {
1372 int move_constructs = 0;
1373 int move_assigns = 0;
1374
Colin Blundell6cc94b52021-05-05 11:13:381375 BindRepeating(&VoidPolymorphic<const MoveCounter&>::Run,
1376 MoveCounter(&move_constructs, &move_assigns));
tzik52dcd672016-02-15 11:54:301377 EXPECT_EQ(1, move_constructs);
1378 EXPECT_EQ(0, move_assigns);
1379
1380 // TODO(tzik): Support binding move-only type into a non-reference parameter
1381 // of a variant of Callback.
1382
tzika43eff02016-03-09 05:46:051383 move_constructs = 0;
1384 move_assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381385 BindRepeating(&VoidPolymorphic<MoveCounter>::Run)
tzika43eff02016-03-09 05:46:051386 .Run(MoveCounter(&move_constructs, &move_assigns));
1387 EXPECT_EQ(1, move_constructs);
1388 EXPECT_EQ(0, move_assigns);
1389
1390 move_constructs = 0;
1391 move_assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381392 BindRepeating(&VoidPolymorphic<MoveCounter>::Run)
tzika43eff02016-03-09 05:46:051393 .Run(MoveCounter(DerivedCopyMoveCounter(
1394 nullptr, nullptr, &move_constructs, &move_assigns)));
1395 EXPECT_EQ(2, move_constructs);
1396 EXPECT_EQ(0, move_assigns);
tzik52dcd672016-02-15 11:54:301397}
1398
1399// Argument constructor usage for non-reference movable-copyable
1400// parameters.
1401// - Bound arguments passed by move are not copied.
1402// - Forwarded arguments are only copied once.
1403// - Forwarded arguments with coercions are only copied once and moved once.
1404TEST_F(BindTest, ArgumentCopiesAndMoves) {
1405 int copies = 0;
1406 int assigns = 0;
1407 int move_constructs = 0;
1408 int move_assigns = 0;
1409
1410 CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
Colin Blundell6cc94b52021-05-05 11:13:381411 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
tzik52dcd672016-02-15 11:54:301412 EXPECT_EQ(1, copies);
1413 EXPECT_EQ(0, assigns);
1414 EXPECT_EQ(0, move_constructs);
1415 EXPECT_EQ(0, move_assigns);
1416
1417 copies = 0;
1418 assigns = 0;
1419 move_constructs = 0;
1420 move_assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381421 BindRepeating(
1422 &VoidPolymorphic<CopyMoveCounter>::Run,
1423 CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
tzik52dcd672016-02-15 11:54:301424 EXPECT_EQ(0, copies);
1425 EXPECT_EQ(0, assigns);
1426 EXPECT_EQ(1, move_constructs);
1427 EXPECT_EQ(0, move_assigns);
1428
1429 copies = 0;
1430 assigns = 0;
1431 move_constructs = 0;
1432 move_assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381433 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter);
tzik52dcd672016-02-15 11:54:301434 EXPECT_EQ(1, copies);
1435 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051436 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301437 EXPECT_EQ(0, move_assigns);
1438
tzik52dcd672016-02-15 11:54:301439 copies = 0;
1440 assigns = 0;
1441 move_constructs = 0;
1442 move_assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381443 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
tzik52dcd672016-02-15 11:54:301444 .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
tzika43eff02016-03-09 05:46:051445 EXPECT_EQ(0, copies);
tzik52dcd672016-02-15 11:54:301446 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051447 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301448 EXPECT_EQ(0, move_assigns);
1449
tzik52dcd672016-02-15 11:54:301450 DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1451 &move_assigns);
1452 copies = 0;
1453 assigns = 0;
1454 move_constructs = 0;
1455 move_assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381456 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
tzik52dcd672016-02-15 11:54:301457 .Run(CopyMoveCounter(derived_counter));
tzika43eff02016-03-09 05:46:051458 EXPECT_EQ(1, copies);
tzik52dcd672016-02-15 11:54:301459 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051460 EXPECT_EQ(1, move_constructs);
tzik52dcd672016-02-15 11:54:301461 EXPECT_EQ(0, move_assigns);
1462
tzik52dcd672016-02-15 11:54:301463 copies = 0;
1464 assigns = 0;
1465 move_constructs = 0;
1466 move_assigns = 0;
Colin Blundell6cc94b52021-05-05 11:13:381467 BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
tzik52dcd672016-02-15 11:54:301468 .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1469 &copies, &assigns, &move_constructs, &move_assigns)));
tzika43eff02016-03-09 05:46:051470 EXPECT_EQ(0, copies);
tzik52dcd672016-02-15 11:54:301471 EXPECT_EQ(0, assigns);
tzika43eff02016-03-09 05:46:051472 EXPECT_EQ(2, move_constructs);
tzik52dcd672016-02-15 11:54:301473 EXPECT_EQ(0, move_assigns);
[email protected]b38d3572011-02-15 01:27:381474}
1475
Peter Kastingca5762732023-12-05 09:28:381476TEST_F(BindTest, RepeatingWithoutPassed) {
1477 // It should be possible to use a move-only type with `BindRepeating` without
1478 // `Passed` if running the callback does not require copying the instance.
1479 struct S {
1480 S() = default;
1481 S(S&&) = default;
1482 S& operator=(S&&) = default;
1483 } s;
1484 BindRepeating([](const S&) {}, std::move(s));
1485}
1486
tzikc1db72652016-07-08 09:42:381487TEST_F(BindTest, CapturelessLambda) {
Colin Blundell6cc94b52021-05-05 11:13:381488 EXPECT_EQ(42, BindRepeating([] { return 42; }).Run());
1489 EXPECT_EQ(42, BindRepeating([](int i) { return i * 7; }, 6).Run());
tzikc1db72652016-07-08 09:42:381490
1491 int x = 1;
Peter Kasting8e4901d2024-02-16 16:34:051492 RepeatingCallback<void(int)> cb =
kylechar650caf02019-07-17 03:25:411493 BindRepeating([](int* x, int i) { *x *= i; }, Unretained(&x));
tzikc1db72652016-07-08 09:42:381494 cb.Run(6);
1495 EXPECT_EQ(6, x);
1496 cb.Run(7);
1497 EXPECT_EQ(42, x);
1498}
1499
tzikf98654b2017-12-02 03:28:581500TEST_F(BindTest, EmptyFunctor) {
1501 struct NonEmptyFunctor {
1502 int operator()() const { return x; }
1503 int x = 42;
1504 };
1505
1506 struct EmptyFunctor {
1507 int operator()() { return 42; }
1508 };
1509
1510 struct EmptyFunctorConst {
1511 int operator()() const { return 42; }
1512 };
1513
Peter Kasting336972e2024-02-09 22:08:001514 EXPECT_EQ(42, BindLambdaForTesting(NonEmptyFunctor()).Run());
tzikf98654b2017-12-02 03:28:581515 EXPECT_EQ(42, BindOnce(EmptyFunctor()).Run());
1516 EXPECT_EQ(42, BindOnce(EmptyFunctorConst()).Run());
1517 EXPECT_EQ(42, BindRepeating(EmptyFunctorConst()).Run());
1518}
1519
1520TEST_F(BindTest, CapturingLambdaForTesting) {
Jan Wilken Dörrie4dc6fad72019-05-22 07:27:561521 // Test copyable lambdas.
tzik4b83dce2017-12-04 19:04:271522 int x = 6;
1523 EXPECT_EQ(42, BindLambdaForTesting([=](int y) { return x * y; }).Run(7));
Jan Wilken Dörrie4dc6fad72019-05-22 07:27:561524 EXPECT_EQ(42,
1525 BindLambdaForTesting([=](int y) mutable { return x *= y; }).Run(7));
tzik4b83dce2017-12-04 19:04:271526 auto f = [x](std::unique_ptr<int> y) { return x * *y; };
1527 EXPECT_EQ(42, BindLambdaForTesting(f).Run(std::make_unique<int>(7)));
Jan Wilken Dörrie4dc6fad72019-05-22 07:27:561528
1529 // Test move-only lambdas.
1530 auto y = std::make_unique<int>(7);
1531 auto g = [y = std::move(y)](int& x) mutable {
1532 return x * *std::exchange(y, nullptr);
1533 };
1534 EXPECT_EQ(42, BindLambdaForTesting(std::move(g)).Run(x));
1535
1536 y = std::make_unique<int>(7);
1537 auto h = [x, y = std::move(y)] { return x * *y; };
1538 EXPECT_EQ(42, BindLambdaForTesting(std::move(h)).Run());
tzikf98654b2017-12-02 03:28:581539}
1540
tzik59aa6bb12016-09-08 10:58:531541TEST_F(BindTest, Cancellation) {
dcheng172b6ad2016-09-24 05:05:571542 EXPECT_CALL(no_ref_, VoidMethodWithIntArg(_)).Times(2);
tzik59aa6bb12016-09-08 10:58:531543
1544 WeakPtrFactory<NoRef> weak_factory(&no_ref_);
tzik44adf072016-10-07 04:34:541545 RepeatingCallback<void(int)> cb =
1546 BindRepeating(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1547 RepeatingClosure cb2 = BindRepeating(cb, 8);
1548 OnceClosure cb3 = BindOnce(cb, 8);
1549
1550 OnceCallback<void(int)> cb4 =
1551 BindOnce(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1552 EXPECT_FALSE(cb4.IsCancelled());
1553
1554 OnceClosure cb5 = BindOnce(std::move(cb4), 8);
tzik59aa6bb12016-09-08 10:58:531555
1556 EXPECT_FALSE(cb.IsCancelled());
1557 EXPECT_FALSE(cb2.IsCancelled());
tzik44adf072016-10-07 04:34:541558 EXPECT_FALSE(cb3.IsCancelled());
1559 EXPECT_FALSE(cb5.IsCancelled());
tzik59aa6bb12016-09-08 10:58:531560
dcheng172b6ad2016-09-24 05:05:571561 cb.Run(6);
tzik59aa6bb12016-09-08 10:58:531562 cb2.Run();
1563
1564 weak_factory.InvalidateWeakPtrs();
1565
1566 EXPECT_TRUE(cb.IsCancelled());
1567 EXPECT_TRUE(cb2.IsCancelled());
tzik44adf072016-10-07 04:34:541568 EXPECT_TRUE(cb3.IsCancelled());
1569 EXPECT_TRUE(cb5.IsCancelled());
tzik59aa6bb12016-09-08 10:58:531570
dcheng172b6ad2016-09-24 05:05:571571 cb.Run(6);
tzik59aa6bb12016-09-08 10:58:531572 cb2.Run();
tzik44adf072016-10-07 04:34:541573 std::move(cb3).Run();
1574 std::move(cb5).Run();
tzik59aa6bb12016-09-08 10:58:531575}
1576
tzik27d1e312016-09-13 05:28:591577TEST_F(BindTest, OnceCallback) {
tzik27d1e312016-09-13 05:28:591578 // Check if Callback variants have declarations of conversions as expected.
1579 // Copy constructor and assignment of RepeatingCallback.
Daniel Cheng91f6fbaf2022-09-16 12:07:481580 static_assert(
Andrew Rayskiyb42fe7522023-10-17 13:16:191581 std::is_constructible_v<RepeatingClosure, const RepeatingClosure&>,
tzik27d1e312016-09-13 05:28:591582 "RepeatingClosure should be copyable.");
Andrew Rayskiyb42fe7522023-10-17 13:16:191583 static_assert(std::is_assignable_v<RepeatingClosure, const RepeatingClosure&>,
1584 "RepeatingClosure should be copy-assignable.");
tzik27d1e312016-09-13 05:28:591585
1586 // Move constructor and assignment of RepeatingCallback.
Andrew Rayskiyb42fe7522023-10-17 13:16:191587 static_assert(std::is_constructible_v<RepeatingClosure, RepeatingClosure&&>,
1588 "RepeatingClosure should be movable.");
1589 static_assert(std::is_assignable_v<RepeatingClosure, RepeatingClosure&&>,
danakj560f5dd2e2017-04-04 20:55:291590 "RepeatingClosure should be move-assignable");
tzik27d1e312016-09-13 05:28:591591
1592 // Conversions from OnceCallback to RepeatingCallback.
Andrew Rayskiyb42fe7522023-10-17 13:16:191593 static_assert(!std::is_constructible_v<RepeatingClosure, const OnceClosure&>,
1594 "OnceClosure should not be convertible to RepeatingClosure.");
1595 static_assert(!std::is_assignable_v<RepeatingClosure, const OnceClosure&>,
1596 "OnceClosure should not be convertible to RepeatingClosure.");
tzik27d1e312016-09-13 05:28:591597
1598 // Destructive conversions from OnceCallback to RepeatingCallback.
Andrew Rayskiyb42fe7522023-10-17 13:16:191599 static_assert(!std::is_constructible_v<RepeatingClosure, OnceClosure&&>,
Daniel Cheng91f6fbaf2022-09-16 12:07:481600 "OnceClosure should not be convertible to RepeatingClosure.");
Andrew Rayskiyb42fe7522023-10-17 13:16:191601 static_assert(!std::is_assignable_v<RepeatingClosure, OnceClosure&&>,
danakj560f5dd2e2017-04-04 20:55:291602 "OnceClosure should not be convertible to RepeatingClosure.");
tzik27d1e312016-09-13 05:28:591603
1604 // Copy constructor and assignment of OnceCallback.
Andrew Rayskiyb42fe7522023-10-17 13:16:191605 static_assert(!std::is_constructible_v<OnceClosure, const OnceClosure&>,
Daniel Cheng91f6fbaf2022-09-16 12:07:481606 "OnceClosure should not be copyable.");
Andrew Rayskiyb42fe7522023-10-17 13:16:191607 static_assert(!std::is_assignable_v<OnceClosure, const OnceClosure&>,
danakj560f5dd2e2017-04-04 20:55:291608 "OnceClosure should not be copy-assignable");
tzik27d1e312016-09-13 05:28:591609
1610 // Move constructor and assignment of OnceCallback.
Andrew Rayskiyb42fe7522023-10-17 13:16:191611 static_assert(std::is_constructible_v<OnceClosure, OnceClosure&&>,
Daniel Cheng91f6fbaf2022-09-16 12:07:481612 "OnceClosure should be movable.");
Andrew Rayskiyb42fe7522023-10-17 13:16:191613 static_assert(std::is_assignable_v<OnceClosure, OnceClosure&&>,
danakj560f5dd2e2017-04-04 20:55:291614 "OnceClosure should be move-assignable.");
tzik27d1e312016-09-13 05:28:591615
1616 // Conversions from RepeatingCallback to OnceCallback.
Andrew Rayskiyb42fe7522023-10-17 13:16:191617 static_assert(std::is_constructible_v<OnceClosure, const RepeatingClosure&>,
1618 "RepeatingClosure should be convertible to OnceClosure.");
1619 static_assert(std::is_assignable_v<OnceClosure, const RepeatingClosure&>,
danakj560f5dd2e2017-04-04 20:55:291620 "RepeatingClosure should be convertible to OnceClosure.");
tzik27d1e312016-09-13 05:28:591621
1622 // Destructive conversions from RepeatingCallback to OnceCallback.
Andrew Rayskiyb42fe7522023-10-17 13:16:191623 static_assert(std::is_constructible_v<OnceClosure, RepeatingClosure&&>,
Daniel Cheng91f6fbaf2022-09-16 12:07:481624 "RepeatingClosure should be convertible to OnceClosure.");
Andrew Rayskiyb42fe7522023-10-17 13:16:191625 static_assert(std::is_assignable_v<OnceClosure, RepeatingClosure&&>,
danakj560f5dd2e2017-04-04 20:55:291626 "RepeatingClosure should be covretible to OnceClosure.");
tzik27d1e312016-09-13 05:28:591627
1628 OnceClosure cb = BindOnce(&VoidPolymorphic<>::Run);
1629 std::move(cb).Run();
1630
1631 // RepeatingCallback should be convertible to OnceCallback.
1632 OnceClosure cb2 = BindRepeating(&VoidPolymorphic<>::Run);
1633 std::move(cb2).Run();
1634
1635 RepeatingClosure cb3 = BindRepeating(&VoidPolymorphic<>::Run);
1636 cb = cb3;
1637 std::move(cb).Run();
1638
Peter Kasting6218bbad2025-01-10 11:26:401639 cb = std::move(cb2); // NOLINT(bugprone-use-after-move)
tzik27d1e312016-09-13 05:28:591640
Jeremy Roman9532f252017-08-16 23:27:241641 OnceCallback<void(int)> cb4 =
1642 BindOnce(&VoidPolymorphic<std::unique_ptr<int>, int>::Run,
1643 std::make_unique<int>(0));
tzik27d1e312016-09-13 05:28:591644 BindOnce(std::move(cb4), 1).Run();
1645}
1646
[email protected]b38d3572011-02-15 01:27:381647// Callback construction and assignment tests.
1648// - Construction from an InvokerStorageHolder should not cause ref/deref.
1649// - Assignment from other callback should only cause one ref
1650//
1651// TODO(ajwong): Is there actually a way to test this?
1652
Xiaohan Wang38e4ebb2022-01-19 06:57:431653#if BUILDFLAG(IS_WIN)
[email protected]054ac7542011-02-27 01:25:591654int __fastcall FastCallFunc(int n) {
1655 return n;
1656}
1657
1658int __stdcall StdCallFunc(int n) {
1659 return n;
1660}
1661
1662// Windows specific calling convention support.
1663// - Can bind a __fastcall function.
1664// - Can bind a __stdcall function.
Sorin Jianu6bc2e352020-04-01 18:01:411665// - Can bind const and non-const __stdcall methods.
[email protected]054ac7542011-02-27 01:25:591666TEST_F(BindTest, WindowsCallingConventions) {
Sorin Jianu6bc2e352020-04-01 18:01:411667 auto fastcall_cb = BindRepeating(&FastCallFunc, 1);
[email protected]054ac7542011-02-27 01:25:591668 EXPECT_EQ(1, fastcall_cb.Run());
1669
Sorin Jianu6bc2e352020-04-01 18:01:411670 auto stdcall_cb = BindRepeating(&StdCallFunc, 2);
[email protected]054ac7542011-02-27 01:25:591671 EXPECT_EQ(2, stdcall_cb.Run());
Sorin Jianu6bc2e352020-04-01 18:01:411672
1673 class MethodHolder {
1674 public:
1675 int __stdcall Func(int n) { return n; }
1676 int __stdcall ConstFunc(int n) const { return -n; }
1677 };
1678
1679 MethodHolder obj;
1680 auto stdcall_method_cb =
Peter Kasting8e4901d2024-02-16 16:34:051681 BindRepeating(&MethodHolder::Func, Unretained(&obj), 1);
Sorin Jianu6bc2e352020-04-01 18:01:411682 EXPECT_EQ(1, stdcall_method_cb.Run());
1683
1684 const MethodHolder const_obj;
1685 auto stdcall_const_method_cb =
Peter Kasting8e4901d2024-02-16 16:34:051686 BindRepeating(&MethodHolder::ConstFunc, Unretained(&const_obj), 1);
Sorin Jianu6bc2e352020-04-01 18:01:411687 EXPECT_EQ(-1, stdcall_const_method_cb.Run());
[email protected]054ac7542011-02-27 01:25:591688}
1689#endif
1690
Peter Kastinga85265e32018-02-15 08:30:231691// Test unwrapping the various wrapping functions.
1692
1693TEST_F(BindTest, UnwrapUnretained) {
1694 int i = 0;
1695 auto unretained = Unretained(&i);
1696 EXPECT_EQ(&i, internal::Unwrap(unretained));
1697 EXPECT_EQ(&i, internal::Unwrap(std::move(unretained)));
1698}
1699
Peter Kastinga85265e32018-02-15 08:30:231700TEST_F(BindTest, UnwrapRetainedRef) {
1701 auto p = MakeRefCounted<RefCountedData<int>>();
1702 auto retained_ref = RetainedRef(p);
1703 EXPECT_EQ(p.get(), internal::Unwrap(retained_ref));
1704 EXPECT_EQ(p.get(), internal::Unwrap(std::move(retained_ref)));
1705}
1706
1707TEST_F(BindTest, UnwrapOwned) {
jdoerrie68f2d51b2019-02-28 17:32:441708 {
1709 int* p = new int;
1710 auto owned = Owned(p);
1711 EXPECT_EQ(p, internal::Unwrap(owned));
1712 EXPECT_EQ(p, internal::Unwrap(std::move(owned)));
1713 }
1714
1715 {
1716 auto p = std::make_unique<int>();
1717 int* raw_p = p.get();
1718 auto owned = Owned(std::move(p));
1719 EXPECT_EQ(raw_p, internal::Unwrap(owned));
1720 EXPECT_EQ(raw_p, internal::Unwrap(std::move(owned)));
1721 }
Peter Kastinga85265e32018-02-15 08:30:231722}
1723
1724TEST_F(BindTest, UnwrapPassed) {
1725 int* p = new int;
1726 auto passed = Passed(WrapUnique(p));
1727 EXPECT_EQ(p, internal::Unwrap(passed).get());
1728
1729 p = new int;
1730 EXPECT_EQ(p, internal::Unwrap(Passed(WrapUnique(p))).get());
1731}
1732
tzikd58a89232018-04-26 04:29:531733TEST_F(BindTest, BindNoexcept) {
Peter Kasting8e4901d2024-02-16 16:34:051734 EXPECT_EQ(42, BindOnce(&Noexcept).Run());
1735 EXPECT_EQ(42, BindOnce(&BindTest::NoexceptMethod, Unretained(this)).Run());
1736 EXPECT_EQ(42,
1737 BindOnce(&BindTest::ConstNoexceptMethod, Unretained(this)).Run());
1738 EXPECT_EQ(42, BindOnce(NoexceptFunctor()).Run());
1739 EXPECT_EQ(42, BindOnce(ConstNoexceptFunctor()).Run());
tzikd58a89232018-04-26 04:29:531740}
1741
Lukasz Anforowicz34d1682a2021-11-19 17:12:171742int PingPong(int* i_ptr) {
1743 return *i_ptr;
1744}
1745
1746TEST_F(BindTest, BindAndCallbacks) {
1747 int i = 123;
1748 raw_ptr<int> p = &i;
1749
Peter Kasting8e4901d2024-02-16 16:34:051750 auto callback = BindOnce(PingPong, Unretained(p));
Lukasz Anforowicz34d1682a2021-11-19 17:12:171751 int res = std::move(callback).Run();
1752 EXPECT_EQ(123, res);
1753}
1754
Peter Kastinga16713f2023-09-02 23:03:101755TEST_F(BindTest, ConvertibleArgs) {
1756 // Create two types S and T, such that you can convert a T to an S, but you
1757 // cannot construct an S from a T.
1758 struct T;
1759 class S {
1760 friend struct T;
1761 explicit S(const T&) {}
1762 };
1763 struct T {
1764 // NOLINTNEXTLINE(google-explicit-constructor)
1765 operator S() const { return S(*this); }
1766 };
1767 static_assert(!std::is_constructible_v<S, T>);
1768 static_assert(std::is_convertible_v<T, S>);
1769
1770 // Ensure it's possible to pass a T to a function expecting an S.
1771 void (*foo)(S) = +[](S) {};
1772 const T t;
Peter Kasting8e4901d2024-02-16 16:34:051773 auto callback = BindOnce(foo, t);
Peter Kastinga16713f2023-09-02 23:03:101774 std::move(callback).Run();
1775}
1776
Peter Kastingbb8853292024-02-15 19:46:181777TEST_F(BindTest, OverloadedOperator) {
1778 // Bind should be able to pick the correct `operator()()` to invoke on a
1779 // functor from the supplied args.
1780 struct S {
1781 int operator()(int x) { return x; }
1782 std::string operator()(std::string s) { return s; }
1783 } s;
1784
1785 EXPECT_EQ(42, BindOnce(s, 42).Run());
1786 EXPECT_EQ("Hello", BindOnce(s, "Hello").Run());
1787}
1788
Peter Kasting2eef24f42024-02-21 18:42:221789TEST_F(BindTest, OverloadedOperatorQualifiers) {
1790 // Bind should be able to pick the correct `operator()()` to invoke on a
1791 // functor when the only difference between the overloads is their qualifiers.
1792 struct S {
1793 int operator()() const& { return 1; }
1794 int operator()() && { return 2; }
1795 } s;
1796
1797 // `BindRepeating()` normally stores a value and passes a const ref to the
1798 // invoked method, regardless of whether lvalue or rvalue was originally
1799 // provided.
1800 EXPECT_EQ(1, BindRepeating(s).Run());
1801 EXPECT_EQ(1, BindRepeating(S()).Run());
1802
1803 // The exception is if `Passed()` is used, which tells `BindRepeating()` to
1804 // move the specified argument during invocation.
1805 EXPECT_EQ(2, BindRepeating(Passed(S())).Run());
1806
1807 // `BindOnce()` also stores a value, but it always moves that value during
1808 // invocation, regardless of whether lvalue or rvalue was originally provided.
1809 EXPECT_EQ(2, BindOnce(s).Run());
1810 EXPECT_EQ(2, BindOnce(S()).Run());
1811}
1812
Peter Kastingbb8853292024-02-15 19:46:181813TEST_F(BindTest, OverloadedOperatorInexactMatch) {
1814 // The Bind machinery guesses signatures for overloaded `operator()()`s based
1815 // on the decay_t<>s of the bound args. But as long as all args are bound and
1816 // are convertible to exactly one overload's params, everything should work,
1817 // even if the guess is slightly incorrect.
1818 struct S {
1819 int operator()(int x) { return x; }
1820 // Machinery will guess that param type here is `std::string`.
1821 std::string operator()(const std::string& s) { return s; }
1822 } s;
1823
1824 EXPECT_EQ(42, BindOnce(s, 42).Run());
1825 EXPECT_EQ("Hello", BindOnce(s, "Hello").Run());
1826}
1827
Andrey Kosyakov64b025b2023-03-31 21:40:151828} // namespace
1829
Peter Kasting8e4901d2024-02-16 16:34:051830// This simulates a race weak pointer that, unlike our `WeakPtr<>`,
Andrey Kosyakov64b025b2023-03-31 21:40:151831// may become invalidated between `operator bool()` is tested and `Lock()`
1832// is called in the implementation of `Unwrap()`.
1833template <typename T>
1834struct MockRacyWeakPtr {
1835 explicit MockRacyWeakPtr(T*) {}
1836 T* Lock() const { return nullptr; }
1837
1838 explicit operator bool() const { return true; }
1839};
1840
1841template <typename T>
1842struct IsWeakReceiver<MockRacyWeakPtr<T>> : std::true_type {};
1843
1844template <typename T>
1845struct BindUnwrapTraits<MockRacyWeakPtr<T>> {
1846 static T* Unwrap(const MockRacyWeakPtr<T>& o) { return o.Lock(); }
1847};
1848
1849template <typename T>
1850struct MaybeValidTraits<MockRacyWeakPtr<T>> {
1851 static bool MaybeValid(const MockRacyWeakPtr<T>& o) { return true; }
1852};
1853
1854namespace {
1855
1856// Note this only covers a case of racy weak pointer invalidation. Other
1857// weak pointer scenarios (such as a valid pointer) are covered
1858// in BindTest.WeakPtrFor{Once,Repeating}.
1859TEST_F(BindTest, BindRacyWeakPtrTest) {
1860 MockRacyWeakPtr<NoRef> weak(&no_ref_);
1861
Peter Kasting8e4901d2024-02-16 16:34:051862 RepeatingClosure cb = BindRepeating(&NoRef::VoidMethod0, weak);
Andrey Kosyakov64b025b2023-03-31 21:40:151863 cb.Run();
1864}
1865
[email protected]8cf362c2012-11-20 08:28:141866// Test null callbacks cause a DCHECK.
1867TEST(BindDeathTest, NullCallback) {
Peter Kasting8e4901d2024-02-16 16:34:051868 RepeatingCallback<void(int)> null_cb;
[email protected]8cf362c2012-11-20 08:28:141869 ASSERT_TRUE(null_cb.is_null());
Peter Kasting8e4901d2024-02-16 16:34:051870 EXPECT_CHECK_DEATH(BindRepeating(null_cb, 42));
Sami Kyostila712b4e32020-04-27 16:51:081871}
1872
1873TEST(BindDeathTest, NullFunctionPointer) {
1874 void (*null_function)(int) = nullptr;
Peter Kasting8e4901d2024-02-16 16:34:051875 EXPECT_DCHECK_DEATH(BindRepeating(null_function, 42));
Sami Kyostila712b4e32020-04-27 16:51:081876}
1877
1878TEST(BindDeathTest, NullCallbackWithoutBoundArgs) {
Peter Kasting8e4901d2024-02-16 16:34:051879 OnceCallback<void(int)> null_cb;
Sami Kyostila712b4e32020-04-27 16:51:081880 ASSERT_TRUE(null_cb.is_null());
Peter Kasting8e4901d2024-02-16 16:34:051881 EXPECT_CHECK_DEATH(BindOnce(std::move(null_cb)));
[email protected]8cf362c2012-11-20 08:28:141882}
1883
tzikefea4f52018-08-02 15:20:461884TEST(BindDeathTest, BanFirstOwnerOfRefCountedType) {
1885 StrictMock<HasRef> has_ref;
1886 EXPECT_DCHECK_DEATH({
1887 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillOnce(Return(false));
Peter Kasting8e4901d2024-02-16 16:34:051888 BindOnce(&HasRef::VoidMethod0, &has_ref);
tzikefea4f52018-08-02 15:20:461889 });
Daniel Cheng00c072a2022-06-11 18:50:371890
1891 EXPECT_DCHECK_DEATH({
1892 raw_ptr<HasRef> rawptr(&has_ref);
1893 EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillOnce(Return(false));
Peter Kasting8e4901d2024-02-16 16:34:051894 BindOnce(&HasRef::VoidMethod0, rawptr);
Daniel Cheng00c072a2022-06-11 18:50:371895 });
tzikefea4f52018-08-02 15:20:461896}
1897
Arthur Sonzogni62e877a2024-04-30 16:09:431898#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) && \
1899 PA_BUILDFLAG(USE_RAW_PTR_BACKUP_REF_IMPL)
Paul Semelb0ce4842022-09-28 08:09:531900
1901void HandleOOM(size_t unused_size) {
1902 LOG(FATAL) << "Out of memory";
1903}
1904
1905// Basic set of options to mostly only enable `BackupRefPtr::kEnabled`.
1906// This avoids the boilerplate of having too much options enabled for simple
1907// testing purpose.
Sorin Jianuad4cc6232024-10-08 19:06:011908static constexpr auto kOnlyEnableBackupRefPtrOptions = [] {
mikta205f9e62023-11-21 11:52:011909 partition_alloc::PartitionOptions opts;
1910 opts.backup_ref_ptr = partition_alloc::PartitionOptions::kEnabled;
1911 return opts;
1912}();
Paul Semelb0ce4842022-09-28 08:09:531913
1914class BindUnretainedDanglingInternalFixture : public BindTest {
1915 public:
1916 void SetUp() override {
1917 partition_alloc::PartitionAllocGlobalInit(HandleOOM);
Paul Semelb0ce4842022-09-28 08:09:531918 enabled_feature_list_.InitWithFeaturesAndParameters(
1919 {{features::kPartitionAllocUnretainedDanglingPtr, {{"mode", "crash"}}}},
1920 {/* disabled_features */});
1921 allocator::InstallUnretainedDanglingRawPtrChecks();
1922 }
Takashi Sakamotobf138122023-02-10 02:41:381923
Paul Semelb0ce4842022-09-28 08:09:531924 void TearDown() override {
1925 enabled_feature_list_.Reset();
1926 allocator::InstallUnretainedDanglingRawPtrChecks();
Paul Semelb0ce4842022-09-28 08:09:531927 }
1928
1929 // In unit tests, allocations being tested need to live in a separate PA
1930 // root so the test code doesn't interfere with various counters. Following
1931 // methods are helpers for managing allocations inside the separate allocator
1932 // root.
Paul Semel6cef46d2023-02-28 10:02:211933 template <typename T,
1934 RawPtrTraits Traits = RawPtrTraits::kEmpty,
1935 typename... Args>
1936 raw_ptr<T, Traits> Alloc(Args&&... args) {
Paul Semelb0ce4842022-09-28 08:09:531937 void* ptr = allocator_.root()->Alloc(sizeof(T), "");
1938 T* p = new (reinterpret_cast<T*>(ptr)) T(std::forward<Args>(args)...);
Paul Semel6cef46d2023-02-28 10:02:211939 return raw_ptr<T, Traits>(p);
Paul Semelb0ce4842022-09-28 08:09:531940 }
Paul Semel6cef46d2023-02-28 10:02:211941 template <typename T, RawPtrTraits Traits>
1942 void Free(raw_ptr<T, Traits>& ptr) {
Arthur Sonzogni994b4d92023-05-31 07:49:351943 allocator_.root()->Free(ptr.ExtractAsDangling());
Paul Semelb0ce4842022-09-28 08:09:531944 }
1945
1946 private:
1947 test::ScopedFeatureList enabled_feature_list_;
Takashi Sakamotobf138122023-02-10 02:41:381948 partition_alloc::PartitionAllocatorForTesting allocator_{
1949 kOnlyEnableBackupRefPtrOptions};
Paul Semelb0ce4842022-09-28 08:09:531950};
1951
1952class BindUnretainedDanglingTest
1953 : public BindUnretainedDanglingInternalFixture {};
1954class BindUnretainedDanglingDeathTest
1955 : public BindUnretainedDanglingInternalFixture {};
1956
1957bool PtrCheckFn(int* p) {
1958 return p != nullptr;
1959}
1960
Paul Semel9d2f06972022-12-12 16:50:441961bool RefCheckFn(const int& p) {
1962 return true;
1963}
1964
Paul Semelff2ca67b2022-12-21 15:46:021965bool MayBeDanglingCheckFn(MayBeDangling<int> p) {
1966 return p != nullptr;
1967}
1968
Paul Semel6cef46d2023-02-28 10:02:211969bool MayBeDanglingAndDummyTraitCheckFn(
1970 MayBeDangling<int, RawPtrTraits::kDummyForTest> p) {
1971 return p != nullptr;
1972}
1973
Paul Semelb0ce4842022-09-28 08:09:531974class ClassWithWeakPtr {
1975 public:
1976 ClassWithWeakPtr() = default;
1977 void RawPtrArg(int* p) { *p = 123; }
Paul Semel9d2f06972022-12-12 16:50:441978 void RawRefArg(int& p) { p = 123; }
Paul Semelb0ce4842022-09-28 08:09:531979 WeakPtr<ClassWithWeakPtr> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
1980
1981 private:
1982 WeakPtrFactory<ClassWithWeakPtr> weak_factory_{this};
1983};
1984
1985TEST_F(BindUnretainedDanglingTest, UnretainedNoDanglingPtr) {
1986 raw_ptr<int> p = Alloc<int>(3);
Peter Kasting8e4901d2024-02-16 16:34:051987 auto callback = BindOnce(PingPong, Unretained(p));
Paul Semelb0ce4842022-09-28 08:09:531988 EXPECT_EQ(std::move(callback).Run(), 3);
1989 Free(p);
1990}
1991
1992TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtr) {
1993 raw_ptr<int> p = Alloc<int>(3);
Peter Kasting8e4901d2024-02-16 16:34:051994 auto callback = BindOnce(MayBeDanglingCheckFn, UnsafeDangling(p));
Paul Semelb0ce4842022-09-28 08:09:531995 Free(p);
1996 EXPECT_EQ(std::move(callback).Run(), true);
1997}
1998
Paul Semel6cef46d2023-02-28 10:02:211999TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtrWithDummyTrait) {
2000 raw_ptr<int, RawPtrTraits::kDummyForTest> p =
2001 Alloc<int, RawPtrTraits::kDummyForTest>(3);
Peter Kasting8e4901d2024-02-16 16:34:052002 auto callback =
2003 BindOnce(MayBeDanglingAndDummyTraitCheckFn, UnsafeDangling(p));
Paul Semel6cef46d2023-02-28 10:02:212004 Free(p);
2005 EXPECT_EQ(std::move(callback).Run(), true);
2006}
2007
2008TEST_F(BindUnretainedDanglingTest,
2009 UnsafeDanglingPtrWithDummyAndDanglingTraits) {
2010 raw_ptr<int, RawPtrTraits::kDummyForTest | RawPtrTraits::kMayDangle> p =
2011 Alloc<int, RawPtrTraits::kDummyForTest | RawPtrTraits::kMayDangle>(3);
Peter Kasting8e4901d2024-02-16 16:34:052012 auto callback =
2013 BindOnce(MayBeDanglingAndDummyTraitCheckFn, UnsafeDangling(p));
Paul Semel6cef46d2023-02-28 10:02:212014 Free(p);
2015 EXPECT_EQ(std::move(callback).Run(), true);
2016}
2017
Paul Semelff2ca67b2022-12-21 15:46:022018TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtrNoRawPtrReceiver) {
2019 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2020 int val = 0;
Peter Kasting8e4901d2024-02-16 16:34:052021 auto callback = BindOnce(&ClassWithWeakPtr::RawPtrArg,
2022 UnsafeDangling(r.get()), Unretained(&val));
Paul Semelff2ca67b2022-12-21 15:46:022023 std::move(callback).Run();
2024 EXPECT_EQ(val, 123);
2025}
2026
Paul Semelb0ce4842022-09-28 08:09:532027TEST_F(BindUnretainedDanglingTest, UnsafeDanglingUntriagedPtr) {
2028 raw_ptr<int> p = Alloc<int>(3);
Peter Kasting8e4901d2024-02-16 16:34:052029 auto callback = BindOnce(PtrCheckFn, UnsafeDanglingUntriaged(p));
Paul Semelb0ce4842022-09-28 08:09:532030 Free(p);
2031 EXPECT_EQ(std::move(callback).Run(), true);
2032}
2033
2034TEST_F(BindUnretainedDanglingTest, UnretainedWeakReceiverValidNoDangling) {
2035 raw_ptr<int> p = Alloc<int>(3);
2036 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
Peter Kasting8e4901d2024-02-16 16:34:052037 auto callback =
2038 BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(), Unretained(p));
Paul Semelb0ce4842022-09-28 08:09:532039 std::move(callback).Run();
2040 EXPECT_EQ(*p, 123);
2041 Free(p);
2042}
2043
Paul Semel9d2f06972022-12-12 16:50:442044TEST_F(BindUnretainedDanglingTest, UnretainedRefWeakReceiverValidNoDangling) {
2045 raw_ptr<int> p = Alloc<int>(3);
2046 int& ref = *p;
2047 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
Peter Kasting8e4901d2024-02-16 16:34:052048 auto callback =
2049 BindOnce(&ClassWithWeakPtr::RawRefArg, r->GetWeakPtr(), std::ref(ref));
Paul Semel9d2f06972022-12-12 16:50:442050 std::move(callback).Run();
2051 EXPECT_EQ(*p, 123);
2052 Free(p);
2053}
Paul Semelb0ce4842022-09-28 08:09:532054
2055TEST_F(BindUnretainedDanglingTest, UnretainedWeakReceiverInvalidNoDangling) {
2056 raw_ptr<int> p = Alloc<int>(3);
2057 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
Peter Kasting8e4901d2024-02-16 16:34:052058 auto callback =
2059 BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(), Unretained(p));
Paul Semelb0ce4842022-09-28 08:09:532060 r.reset();
2061 Free(p);
2062 std::move(callback).Run();
2063 // Should reach this point without crashing; there is a dangling pointer, but
2064 // the callback is cancelled because the WeakPtr is already invalidated.
2065}
2066
Paul Semel9d2f06972022-12-12 16:50:442067TEST_F(BindUnretainedDanglingTest, UnretainedRefWeakReceiverInvalidNoDangling) {
2068 raw_ptr<int> p = Alloc<int>(3);
2069 int& ref = *p;
2070 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
Peter Kasting8e4901d2024-02-16 16:34:052071 auto callback =
2072 BindOnce(&ClassWithWeakPtr::RawRefArg, r->GetWeakPtr(), std::ref(ref));
Paul Semel9d2f06972022-12-12 16:50:442073 r.reset();
2074 Free(p);
2075 std::move(callback).Run();
2076 // Should reach this point without crashing; there is a dangling pointer, but
2077 // the callback is cancelled because the WeakPtr is already invalidated.
2078}
2079
2080TEST_F(BindUnretainedDanglingTest, UnretainedRefUnsafeDangling) {
2081 raw_ptr<int> p = Alloc<int>(3);
2082 int& ref = *p;
Peter Kasting8e4901d2024-02-16 16:34:052083 auto callback = BindOnce(RefCheckFn, UnsafeDangling(raw_ref<int>(ref)));
Paul Semel9d2f06972022-12-12 16:50:442084 Free(p);
2085 EXPECT_EQ(std::move(callback).Run(), true);
2086 // Should reach this point without crashing; there is a dangling pointer, but
2087 // the we marked the reference as `UnsafeDangling`.
2088}
2089
2090TEST_F(BindUnretainedDanglingTest, UnretainedRefUnsafeDanglingUntriaged) {
2091 raw_ptr<int> p = Alloc<int>(3);
2092 int& ref = *p;
Peter Kasting8e4901d2024-02-16 16:34:052093 auto callback =
2094 BindOnce(RefCheckFn, UnsafeDanglingUntriaged(raw_ref<const int>(ref)));
Paul Semel9d2f06972022-12-12 16:50:442095 Free(p);
2096 EXPECT_EQ(std::move(callback).Run(), true);
2097 // Should reach this point without crashing; there is a dangling pointer, but
2098 // the we marked the reference as `UnsafeDanglingUntriaged`.
2099}
2100
2101// Death tests misbehave on Android, http://crbug.com/643760.
2102#if defined(GTEST_HAS_DEATH_TEST) && !BUILDFLAG(IS_ANDROID)
2103
2104int FuncWithRefArgument(int& i_ptr) {
2105 return i_ptr;
2106}
2107
Paul Semelb0ce4842022-09-28 08:09:532108TEST_F(BindUnretainedDanglingDeathTest, UnretainedDanglingPtr) {
2109 raw_ptr<int> p = Alloc<int>(3);
Peter Kasting8e4901d2024-02-16 16:34:052110 auto callback = BindOnce(PingPong, Unretained(p));
Paul Semelb0ce4842022-09-28 08:09:532111 Free(p);
2112 EXPECT_DEATH(std::move(callback).Run(), "");
2113}
2114
Paul Semel9d2f06972022-12-12 16:50:442115TEST_F(BindUnretainedDanglingDeathTest, UnretainedRefDanglingPtr) {
2116 raw_ptr<int> p = Alloc<int>(3);
2117 int& ref = *p;
Peter Kasting8e4901d2024-02-16 16:34:052118 auto callback = BindOnce(FuncWithRefArgument, std::ref(ref));
Paul Semel9d2f06972022-12-12 16:50:442119 Free(p);
2120 EXPECT_DEATH(std::move(callback).Run(), "");
2121}
2122
2123TEST_F(BindUnretainedDanglingDeathTest,
2124 UnretainedRefWithManualUnretainedDanglingPtr) {
2125 raw_ptr<int> p = Alloc<int>(3);
2126 int& ref = *p;
Peter Kasting8e4901d2024-02-16 16:34:052127 auto callback = BindOnce(FuncWithRefArgument, Unretained(raw_ref<int>(ref)));
Paul Semel9d2f06972022-12-12 16:50:442128 Free(p);
2129 EXPECT_DEATH(std::move(callback).Run(), "");
2130}
2131
Paul Semelb0ce4842022-09-28 08:09:532132TEST_F(BindUnretainedDanglingDeathTest, UnretainedWeakReceiverDangling) {
2133 raw_ptr<int> p = Alloc<int>(3);
2134 std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
Peter Kasting8e4901d2024-02-16 16:34:052135 auto callback =
2136 BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(), Unretained(p));
Paul Semelb0ce4842022-09-28 08:09:532137 Free(p);
2138 EXPECT_DEATH(std::move(callback).Run(), "");
2139}
2140
2141#endif // defined(GTEST_HAS_DEATH_TEST) && !BUILDFLAG(IS_ANDROID)
2142
Arthur Sonzogni62e877a2024-04-30 16:09:432143#endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) &&
2144 // PA_BUILDFLAG(USE_RAW_PTR_BACKUP_REF_IMPL)
Paul Semelb0ce4842022-09-28 08:09:532145
[email protected]b38d3572011-02-15 01:27:382146} // namespace
2147} // namespace base