1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <functional>
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <string>
10*6777b538SAndroid Build Coastguard Worker #include <utility>
11*6777b538SAndroid Build Coastguard Worker #include <vector>
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker #include "base/allocator/partition_alloc_features.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/allocator/partition_alloc_support.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ref.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
25*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
26*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/dangling_raw_ptr_checks.h"
27*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/partition_alloc_buildflags.h"
28*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/partition_alloc_for_testing.h"
29*6777b538SAndroid Build Coastguard Worker #include "partition_alloc/partition_root.h"
30*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
31*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker using ::testing::_;
34*6777b538SAndroid Build Coastguard Worker using ::testing::AnyNumber;
35*6777b538SAndroid Build Coastguard Worker using ::testing::ByMove;
36*6777b538SAndroid Build Coastguard Worker using ::testing::Mock;
37*6777b538SAndroid Build Coastguard Worker using ::testing::Return;
38*6777b538SAndroid Build Coastguard Worker using ::testing::StrictMock;
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker namespace base {
41*6777b538SAndroid Build Coastguard Worker namespace {
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker class NoRef {
44*6777b538SAndroid Build Coastguard Worker public:
45*6777b538SAndroid Build Coastguard Worker NoRef() = default;
46*6777b538SAndroid Build Coastguard Worker NoRef(const NoRef&) = delete;
47*6777b538SAndroid Build Coastguard Worker // Particularly important in this test to ensure no copies are made.
48*6777b538SAndroid Build Coastguard Worker NoRef& operator=(const NoRef&) = delete;
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker MOCK_METHOD0(VoidMethod0, void());
51*6777b538SAndroid Build Coastguard Worker MOCK_CONST_METHOD0(VoidConstMethod0, void());
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker MOCK_METHOD0(IntMethod0, int());
54*6777b538SAndroid Build Coastguard Worker MOCK_CONST_METHOD0(IntConstMethod0, int());
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker MOCK_METHOD1(VoidMethodWithIntArg, void(int));
57*6777b538SAndroid Build Coastguard Worker MOCK_METHOD0(UniquePtrMethod0, std::unique_ptr<int>());
58*6777b538SAndroid Build Coastguard Worker };
59*6777b538SAndroid Build Coastguard Worker
60*6777b538SAndroid Build Coastguard Worker class HasRef : public NoRef {
61*6777b538SAndroid Build Coastguard Worker public:
62*6777b538SAndroid Build Coastguard Worker HasRef() = default;
63*6777b538SAndroid Build Coastguard Worker HasRef(const HasRef&) = delete;
64*6777b538SAndroid Build Coastguard Worker // Particularly important in this test to ensure no copies are made.
65*6777b538SAndroid Build Coastguard Worker HasRef& operator=(const HasRef&) = delete;
66*6777b538SAndroid Build Coastguard Worker
67*6777b538SAndroid Build Coastguard Worker MOCK_CONST_METHOD0(AddRef, void());
68*6777b538SAndroid Build Coastguard Worker MOCK_CONST_METHOD0(Release, bool());
69*6777b538SAndroid Build Coastguard Worker MOCK_CONST_METHOD0(HasAtLeastOneRef, bool());
70*6777b538SAndroid Build Coastguard Worker };
71*6777b538SAndroid Build Coastguard Worker
72*6777b538SAndroid Build Coastguard Worker class HasRefPrivateDtor : public HasRef {
73*6777b538SAndroid Build Coastguard Worker private:
74*6777b538SAndroid Build Coastguard Worker ~HasRefPrivateDtor() = default;
75*6777b538SAndroid Build Coastguard Worker };
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker static const int kParentValue = 1;
78*6777b538SAndroid Build Coastguard Worker static const int kChildValue = 2;
79*6777b538SAndroid Build Coastguard Worker
80*6777b538SAndroid Build Coastguard Worker class Parent {
81*6777b538SAndroid Build Coastguard Worker public:
AddRef() const82*6777b538SAndroid Build Coastguard Worker void AddRef() const {}
Release() const83*6777b538SAndroid Build Coastguard Worker void Release() const {}
HasAtLeastOneRef() const84*6777b538SAndroid Build Coastguard Worker bool HasAtLeastOneRef() const { return true; }
VirtualSet()85*6777b538SAndroid Build Coastguard Worker virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()86*6777b538SAndroid Build Coastguard Worker void NonVirtualSet() { value = kParentValue; }
87*6777b538SAndroid Build Coastguard Worker int value;
88*6777b538SAndroid Build Coastguard Worker };
89*6777b538SAndroid Build Coastguard Worker
90*6777b538SAndroid Build Coastguard Worker class Child : public Parent {
91*6777b538SAndroid Build Coastguard Worker public:
VirtualSet()92*6777b538SAndroid Build Coastguard Worker void VirtualSet() override { value = kChildValue; }
NonVirtualSet()93*6777b538SAndroid Build Coastguard Worker void NonVirtualSet() { value = kChildValue; }
94*6777b538SAndroid Build Coastguard Worker };
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker class NoRefParent {
97*6777b538SAndroid Build Coastguard Worker public:
VirtualSet()98*6777b538SAndroid Build Coastguard Worker virtual void VirtualSet() { value = kParentValue; }
NonVirtualSet()99*6777b538SAndroid Build Coastguard Worker void NonVirtualSet() { value = kParentValue; }
100*6777b538SAndroid Build Coastguard Worker int value;
101*6777b538SAndroid Build Coastguard Worker };
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Worker class NoRefChild : public NoRefParent {
VirtualSet()104*6777b538SAndroid Build Coastguard Worker void VirtualSet() override { value = kChildValue; }
NonVirtualSet()105*6777b538SAndroid Build Coastguard Worker void NonVirtualSet() { value = kChildValue; }
106*6777b538SAndroid Build Coastguard Worker };
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard Worker // Used for probing the number of copies and moves that occur if a type must be
109*6777b538SAndroid Build Coastguard Worker // coerced during argument forwarding in the Run() methods.
110*6777b538SAndroid Build Coastguard Worker struct DerivedCopyMoveCounter {
DerivedCopyMoveCounterbase::__anon8a4af9fd0111::DerivedCopyMoveCounter111*6777b538SAndroid Build Coastguard Worker DerivedCopyMoveCounter(int* copies,
112*6777b538SAndroid Build Coastguard Worker int* assigns,
113*6777b538SAndroid Build Coastguard Worker int* move_constructs,
114*6777b538SAndroid Build Coastguard Worker int* move_assigns)
115*6777b538SAndroid Build Coastguard Worker : copies_(copies),
116*6777b538SAndroid Build Coastguard Worker assigns_(assigns),
117*6777b538SAndroid Build Coastguard Worker move_constructs_(move_constructs),
118*6777b538SAndroid Build Coastguard Worker move_assigns_(move_assigns) {}
119*6777b538SAndroid Build Coastguard Worker raw_ptr<int> copies_;
120*6777b538SAndroid Build Coastguard Worker raw_ptr<int> assigns_;
121*6777b538SAndroid Build Coastguard Worker raw_ptr<int> move_constructs_;
122*6777b538SAndroid Build Coastguard Worker raw_ptr<int> move_assigns_;
123*6777b538SAndroid Build Coastguard Worker };
124*6777b538SAndroid Build Coastguard Worker
125*6777b538SAndroid Build Coastguard Worker // Used for probing the number of copies and moves in an argument.
126*6777b538SAndroid Build Coastguard Worker class CopyMoveCounter {
127*6777b538SAndroid Build Coastguard Worker public:
CopyMoveCounter(int * copies,int * assigns,int * move_constructs,int * move_assigns)128*6777b538SAndroid Build Coastguard Worker CopyMoveCounter(int* copies,
129*6777b538SAndroid Build Coastguard Worker int* assigns,
130*6777b538SAndroid Build Coastguard Worker int* move_constructs,
131*6777b538SAndroid Build Coastguard Worker int* move_assigns)
132*6777b538SAndroid Build Coastguard Worker : copies_(copies),
133*6777b538SAndroid Build Coastguard Worker assigns_(assigns),
134*6777b538SAndroid Build Coastguard Worker move_constructs_(move_constructs),
135*6777b538SAndroid Build Coastguard Worker move_assigns_(move_assigns) {}
136*6777b538SAndroid Build Coastguard Worker
CopyMoveCounter(const CopyMoveCounter & other)137*6777b538SAndroid Build Coastguard Worker CopyMoveCounter(const CopyMoveCounter& other)
138*6777b538SAndroid Build Coastguard Worker : copies_(other.copies_),
139*6777b538SAndroid Build Coastguard Worker assigns_(other.assigns_),
140*6777b538SAndroid Build Coastguard Worker move_constructs_(other.move_constructs_),
141*6777b538SAndroid Build Coastguard Worker move_assigns_(other.move_assigns_) {
142*6777b538SAndroid Build Coastguard Worker (*copies_)++;
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker
CopyMoveCounter(CopyMoveCounter && other)145*6777b538SAndroid Build Coastguard Worker CopyMoveCounter(CopyMoveCounter&& other)
146*6777b538SAndroid Build Coastguard Worker : copies_(other.copies_),
147*6777b538SAndroid Build Coastguard Worker assigns_(other.assigns_),
148*6777b538SAndroid Build Coastguard Worker move_constructs_(other.move_constructs_),
149*6777b538SAndroid Build Coastguard Worker move_assigns_(other.move_assigns_) {
150*6777b538SAndroid Build Coastguard Worker (*move_constructs_)++;
151*6777b538SAndroid Build Coastguard Worker }
152*6777b538SAndroid Build Coastguard Worker
153*6777b538SAndroid Build Coastguard Worker // Probing for copies from coercion.
CopyMoveCounter(const DerivedCopyMoveCounter & other)154*6777b538SAndroid Build Coastguard Worker explicit CopyMoveCounter(const DerivedCopyMoveCounter& other)
155*6777b538SAndroid Build Coastguard Worker : copies_(other.copies_),
156*6777b538SAndroid Build Coastguard Worker assigns_(other.assigns_),
157*6777b538SAndroid Build Coastguard Worker move_constructs_(other.move_constructs_),
158*6777b538SAndroid Build Coastguard Worker move_assigns_(other.move_assigns_) {
159*6777b538SAndroid Build Coastguard Worker (*copies_)++;
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker // Probing for moves from coercion.
CopyMoveCounter(DerivedCopyMoveCounter && other)163*6777b538SAndroid Build Coastguard Worker explicit CopyMoveCounter(DerivedCopyMoveCounter&& other)
164*6777b538SAndroid Build Coastguard Worker : copies_(other.copies_),
165*6777b538SAndroid Build Coastguard Worker assigns_(other.assigns_),
166*6777b538SAndroid Build Coastguard Worker move_constructs_(other.move_constructs_),
167*6777b538SAndroid Build Coastguard Worker move_assigns_(other.move_assigns_) {
168*6777b538SAndroid Build Coastguard Worker (*move_constructs_)++;
169*6777b538SAndroid Build Coastguard Worker }
170*6777b538SAndroid Build Coastguard Worker
operator =(const CopyMoveCounter & rhs)171*6777b538SAndroid Build Coastguard Worker const CopyMoveCounter& operator=(const CopyMoveCounter& rhs) {
172*6777b538SAndroid Build Coastguard Worker copies_ = rhs.copies_;
173*6777b538SAndroid Build Coastguard Worker assigns_ = rhs.assigns_;
174*6777b538SAndroid Build Coastguard Worker move_constructs_ = rhs.move_constructs_;
175*6777b538SAndroid Build Coastguard Worker move_assigns_ = rhs.move_assigns_;
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker (*assigns_)++;
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker return *this;
180*6777b538SAndroid Build Coastguard Worker }
181*6777b538SAndroid Build Coastguard Worker
operator =(CopyMoveCounter && rhs)182*6777b538SAndroid Build Coastguard Worker const CopyMoveCounter& operator=(CopyMoveCounter&& rhs) {
183*6777b538SAndroid Build Coastguard Worker copies_ = rhs.copies_;
184*6777b538SAndroid Build Coastguard Worker assigns_ = rhs.assigns_;
185*6777b538SAndroid Build Coastguard Worker move_constructs_ = rhs.move_constructs_;
186*6777b538SAndroid Build Coastguard Worker move_assigns_ = rhs.move_assigns_;
187*6777b538SAndroid Build Coastguard Worker
188*6777b538SAndroid Build Coastguard Worker (*move_assigns_)++;
189*6777b538SAndroid Build Coastguard Worker
190*6777b538SAndroid Build Coastguard Worker return *this;
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker
copies() const193*6777b538SAndroid Build Coastguard Worker int copies() const { return *copies_; }
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker private:
196*6777b538SAndroid Build Coastguard Worker raw_ptr<int> copies_;
197*6777b538SAndroid Build Coastguard Worker raw_ptr<int> assigns_;
198*6777b538SAndroid Build Coastguard Worker raw_ptr<int> move_constructs_;
199*6777b538SAndroid Build Coastguard Worker raw_ptr<int> move_assigns_;
200*6777b538SAndroid Build Coastguard Worker };
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker // Used for probing the number of copies in an argument. The instance is a
203*6777b538SAndroid Build Coastguard Worker // copyable and non-movable type.
204*6777b538SAndroid Build Coastguard Worker class CopyCounter {
205*6777b538SAndroid Build Coastguard Worker public:
CopyCounter(int * copies,int * assigns)206*6777b538SAndroid Build Coastguard Worker CopyCounter(int* copies, int* assigns)
207*6777b538SAndroid Build Coastguard Worker : counter_(copies, assigns, nullptr, nullptr) {}
208*6777b538SAndroid Build Coastguard Worker CopyCounter(const CopyCounter& other) = default;
209*6777b538SAndroid Build Coastguard Worker CopyCounter& operator=(const CopyCounter& other) = default;
210*6777b538SAndroid Build Coastguard Worker
CopyCounter(const DerivedCopyMoveCounter & other)211*6777b538SAndroid Build Coastguard Worker explicit CopyCounter(const DerivedCopyMoveCounter& other) : counter_(other) {}
212*6777b538SAndroid Build Coastguard Worker
copies() const213*6777b538SAndroid Build Coastguard Worker int copies() const { return counter_.copies(); }
214*6777b538SAndroid Build Coastguard Worker
215*6777b538SAndroid Build Coastguard Worker private:
216*6777b538SAndroid Build Coastguard Worker CopyMoveCounter counter_;
217*6777b538SAndroid Build Coastguard Worker };
218*6777b538SAndroid Build Coastguard Worker
219*6777b538SAndroid Build Coastguard Worker // Used for probing the number of moves in an argument. The instance is a
220*6777b538SAndroid Build Coastguard Worker // non-copyable and movable type.
221*6777b538SAndroid Build Coastguard Worker class MoveCounter {
222*6777b538SAndroid Build Coastguard Worker public:
MoveCounter(int * move_constructs,int * move_assigns)223*6777b538SAndroid Build Coastguard Worker MoveCounter(int* move_constructs, int* move_assigns)
224*6777b538SAndroid Build Coastguard Worker : counter_(nullptr, nullptr, move_constructs, move_assigns) {}
MoveCounter(MoveCounter && other)225*6777b538SAndroid Build Coastguard Worker MoveCounter(MoveCounter&& other) : counter_(std::move(other.counter_)) {}
operator =(MoveCounter && other)226*6777b538SAndroid Build Coastguard Worker MoveCounter& operator=(MoveCounter&& other) {
227*6777b538SAndroid Build Coastguard Worker counter_ = std::move(other.counter_);
228*6777b538SAndroid Build Coastguard Worker return *this;
229*6777b538SAndroid Build Coastguard Worker }
230*6777b538SAndroid Build Coastguard Worker
MoveCounter(DerivedCopyMoveCounter && other)231*6777b538SAndroid Build Coastguard Worker explicit MoveCounter(DerivedCopyMoveCounter&& other)
232*6777b538SAndroid Build Coastguard Worker : counter_(std::move(other)) {}
233*6777b538SAndroid Build Coastguard Worker
234*6777b538SAndroid Build Coastguard Worker private:
235*6777b538SAndroid Build Coastguard Worker CopyMoveCounter counter_;
236*6777b538SAndroid Build Coastguard Worker };
237*6777b538SAndroid Build Coastguard Worker
238*6777b538SAndroid Build Coastguard Worker class DeleteCounter {
239*6777b538SAndroid Build Coastguard Worker public:
DeleteCounter(int * deletes)240*6777b538SAndroid Build Coastguard Worker explicit DeleteCounter(int* deletes) : deletes_(deletes) {}
241*6777b538SAndroid Build Coastguard Worker
~DeleteCounter()242*6777b538SAndroid Build Coastguard Worker ~DeleteCounter() { (*deletes_)++; }
243*6777b538SAndroid Build Coastguard Worker
VoidMethod0()244*6777b538SAndroid Build Coastguard Worker void VoidMethod0() {}
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard Worker private:
247*6777b538SAndroid Build Coastguard Worker raw_ptr<int> deletes_;
248*6777b538SAndroid Build Coastguard Worker };
249*6777b538SAndroid Build Coastguard Worker
250*6777b538SAndroid Build Coastguard Worker template <typename T>
PassThru(T scoper)251*6777b538SAndroid Build Coastguard Worker T PassThru(T scoper) {
252*6777b538SAndroid Build Coastguard Worker return scoper;
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker
255*6777b538SAndroid Build Coastguard Worker // Some test functions that we can Bind to.
256*6777b538SAndroid Build Coastguard Worker template <typename T>
PolymorphicIdentity(T t)257*6777b538SAndroid Build Coastguard Worker T PolymorphicIdentity(T t) {
258*6777b538SAndroid Build Coastguard Worker return t;
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker
261*6777b538SAndroid Build Coastguard Worker template <typename... Ts>
262*6777b538SAndroid Build Coastguard Worker struct VoidPolymorphic {
Runbase::__anon8a4af9fd0111::VoidPolymorphic263*6777b538SAndroid Build Coastguard Worker static void Run(Ts... t) {}
264*6777b538SAndroid Build Coastguard Worker };
265*6777b538SAndroid Build Coastguard Worker
Identity(int n)266*6777b538SAndroid Build Coastguard Worker int Identity(int n) {
267*6777b538SAndroid Build Coastguard Worker return n;
268*6777b538SAndroid Build Coastguard Worker }
269*6777b538SAndroid Build Coastguard Worker
ArrayGet(const int array[],int n)270*6777b538SAndroid Build Coastguard Worker int ArrayGet(const int array[], int n) {
271*6777b538SAndroid Build Coastguard Worker return array[n];
272*6777b538SAndroid Build Coastguard Worker }
273*6777b538SAndroid Build Coastguard Worker
Sum(int a,int b,int c,int d,int e,int f)274*6777b538SAndroid Build Coastguard Worker int Sum(int a, int b, int c, int d, int e, int f) {
275*6777b538SAndroid Build Coastguard Worker return a + b + c + d + e + f;
276*6777b538SAndroid Build Coastguard Worker }
277*6777b538SAndroid Build Coastguard Worker
CStringIdentity(const char * s)278*6777b538SAndroid Build Coastguard Worker const char* CStringIdentity(const char* s) {
279*6777b538SAndroid Build Coastguard Worker return s;
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker
GetCopies(const CopyMoveCounter & counter)282*6777b538SAndroid Build Coastguard Worker int GetCopies(const CopyMoveCounter& counter) {
283*6777b538SAndroid Build Coastguard Worker return counter.copies();
284*6777b538SAndroid Build Coastguard Worker }
285*6777b538SAndroid Build Coastguard Worker
UnwrapNoRefParent(NoRefParent p)286*6777b538SAndroid Build Coastguard Worker int UnwrapNoRefParent(NoRefParent p) {
287*6777b538SAndroid Build Coastguard Worker return p.value;
288*6777b538SAndroid Build Coastguard Worker }
289*6777b538SAndroid Build Coastguard Worker
UnwrapNoRefParentPtr(NoRefParent * p)290*6777b538SAndroid Build Coastguard Worker int UnwrapNoRefParentPtr(NoRefParent* p) {
291*6777b538SAndroid Build Coastguard Worker return p->value;
292*6777b538SAndroid Build Coastguard Worker }
293*6777b538SAndroid Build Coastguard Worker
UnwrapNoRefParentConstRef(const NoRefParent & p)294*6777b538SAndroid Build Coastguard Worker int UnwrapNoRefParentConstRef(const NoRefParent& p) {
295*6777b538SAndroid Build Coastguard Worker return p.value;
296*6777b538SAndroid Build Coastguard Worker }
297*6777b538SAndroid Build Coastguard Worker
RefArgSet(int & n)298*6777b538SAndroid Build Coastguard Worker void RefArgSet(int& n) {
299*6777b538SAndroid Build Coastguard Worker n = 2;
300*6777b538SAndroid Build Coastguard Worker }
301*6777b538SAndroid Build Coastguard Worker
PtrArgSet(int * n)302*6777b538SAndroid Build Coastguard Worker void PtrArgSet(int* n) {
303*6777b538SAndroid Build Coastguard Worker *n = 2;
304*6777b538SAndroid Build Coastguard Worker }
305*6777b538SAndroid Build Coastguard Worker
FunctionWithWeakFirstParam(WeakPtr<NoRef> o,int n)306*6777b538SAndroid Build Coastguard Worker int FunctionWithWeakFirstParam(WeakPtr<NoRef> o, int n) {
307*6777b538SAndroid Build Coastguard Worker return n;
308*6777b538SAndroid Build Coastguard Worker }
309*6777b538SAndroid Build Coastguard Worker
FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef> & o,int n)310*6777b538SAndroid Build Coastguard Worker int FunctionWithScopedRefptrFirstParam(const scoped_refptr<HasRef>& o, int n) {
311*6777b538SAndroid Build Coastguard Worker return n;
312*6777b538SAndroid Build Coastguard Worker }
313*6777b538SAndroid Build Coastguard Worker
TakesACallback(const RepeatingClosure & callback)314*6777b538SAndroid Build Coastguard Worker void TakesACallback(const RepeatingClosure& callback) {
315*6777b538SAndroid Build Coastguard Worker callback.Run();
316*6777b538SAndroid Build Coastguard Worker }
317*6777b538SAndroid Build Coastguard Worker
Noexcept()318*6777b538SAndroid Build Coastguard Worker int Noexcept() noexcept {
319*6777b538SAndroid Build Coastguard Worker return 42;
320*6777b538SAndroid Build Coastguard Worker }
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker class NoexceptFunctor {
323*6777b538SAndroid Build Coastguard Worker public:
operator ()()324*6777b538SAndroid Build Coastguard Worker int operator()() noexcept { return 42; }
325*6777b538SAndroid Build Coastguard Worker };
326*6777b538SAndroid Build Coastguard Worker
327*6777b538SAndroid Build Coastguard Worker class ConstNoexceptFunctor {
328*6777b538SAndroid Build Coastguard Worker public:
operator ()()329*6777b538SAndroid Build Coastguard Worker int operator()() noexcept { return 42; }
330*6777b538SAndroid Build Coastguard Worker };
331*6777b538SAndroid Build Coastguard Worker
332*6777b538SAndroid Build Coastguard Worker class BindTest : public ::testing::Test {
333*6777b538SAndroid Build Coastguard Worker public:
BindTest()334*6777b538SAndroid Build Coastguard Worker BindTest() {
335*6777b538SAndroid Build Coastguard Worker const_has_ref_ptr_ = &has_ref_;
336*6777b538SAndroid Build Coastguard Worker const_no_ref_ptr_ = &no_ref_;
337*6777b538SAndroid Build Coastguard Worker static_func_mock_ptr = &static_func_mock_;
338*6777b538SAndroid Build Coastguard Worker }
339*6777b538SAndroid Build Coastguard Worker BindTest(const BindTest&) = delete;
340*6777b538SAndroid Build Coastguard Worker BindTest& operator=(const BindTest&) = delete;
341*6777b538SAndroid Build Coastguard Worker ~BindTest() override = default;
342*6777b538SAndroid Build Coastguard Worker
VoidFunc0()343*6777b538SAndroid Build Coastguard Worker static void VoidFunc0() { static_func_mock_ptr->VoidMethod0(); }
344*6777b538SAndroid Build Coastguard Worker
IntFunc0()345*6777b538SAndroid Build Coastguard Worker static int IntFunc0() { return static_func_mock_ptr->IntMethod0(); }
NoexceptMethod()346*6777b538SAndroid Build Coastguard Worker int NoexceptMethod() noexcept { return 42; }
ConstNoexceptMethod() const347*6777b538SAndroid Build Coastguard Worker int ConstNoexceptMethod() const noexcept { return 42; }
348*6777b538SAndroid Build Coastguard Worker
349*6777b538SAndroid Build Coastguard Worker protected:
350*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef> no_ref_;
351*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref_;
352*6777b538SAndroid Build Coastguard Worker raw_ptr<const HasRef> const_has_ref_ptr_;
353*6777b538SAndroid Build Coastguard Worker raw_ptr<const NoRef> const_no_ref_ptr_;
354*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef> static_func_mock_;
355*6777b538SAndroid Build Coastguard Worker
356*6777b538SAndroid Build Coastguard Worker // Used by the static functions to perform expectations.
357*6777b538SAndroid Build Coastguard Worker static StrictMock<NoRef>* static_func_mock_ptr;
358*6777b538SAndroid Build Coastguard Worker };
359*6777b538SAndroid Build Coastguard Worker
360*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef>* BindTest::static_func_mock_ptr;
361*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef>* g_func_mock_ptr;
362*6777b538SAndroid Build Coastguard Worker
VoidFunc0()363*6777b538SAndroid Build Coastguard Worker void VoidFunc0() {
364*6777b538SAndroid Build Coastguard Worker g_func_mock_ptr->VoidMethod0();
365*6777b538SAndroid Build Coastguard Worker }
366*6777b538SAndroid Build Coastguard Worker
IntFunc0()367*6777b538SAndroid Build Coastguard Worker int IntFunc0() {
368*6777b538SAndroid Build Coastguard Worker return g_func_mock_ptr->IntMethod0();
369*6777b538SAndroid Build Coastguard Worker }
370*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,BasicTest)371*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, BasicTest) {
372*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int, int, int)> cb = BindRepeating(&Sum, 32, 16, 8);
373*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(92, cb.Run(13, 12, 11));
374*6777b538SAndroid Build Coastguard Worker
375*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int, int, int, int, int, int)> c1 = BindRepeating(&Sum);
376*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(69, c1.Run(14, 13, 12, 11, 10, 9));
377*6777b538SAndroid Build Coastguard Worker
378*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int, int, int)> c2 = BindRepeating(c1, 32, 16, 8);
379*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(86, c2.Run(11, 10, 9));
380*6777b538SAndroid Build Coastguard Worker
381*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> c3 = BindRepeating(c2, 4, 2, 1);
382*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(63, c3.Run());
383*6777b538SAndroid Build Coastguard Worker }
384*6777b538SAndroid Build Coastguard Worker
385*6777b538SAndroid Build Coastguard Worker // Test that currying the rvalue result of another BindRepeating() works
386*6777b538SAndroid Build Coastguard Worker // correctly.
387*6777b538SAndroid Build Coastguard Worker // - rvalue should be usable as argument to BindRepeating().
388*6777b538SAndroid Build Coastguard Worker // - multiple runs of resulting RepeatingCallback remain valid.
TEST_F(BindTest,CurryingRvalueResultOfBind)389*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, CurryingRvalueResultOfBind) {
390*6777b538SAndroid Build Coastguard Worker int n = 0;
391*6777b538SAndroid Build Coastguard Worker RepeatingClosure cb =
392*6777b538SAndroid Build Coastguard Worker BindRepeating(&TakesACallback, BindRepeating(&PtrArgSet, &n));
393*6777b538SAndroid Build Coastguard Worker
394*6777b538SAndroid Build Coastguard Worker // If we implement BindRepeating() such that the return value has
395*6777b538SAndroid Build Coastguard Worker // auto_ptr-like semantics, the second call here will fail because ownership
396*6777b538SAndroid Build Coastguard Worker // of the internal BindState<> would have been transferred to a *temporary*
397*6777b538SAndroid Build Coastguard Worker // construction of a RepeatingCallback object on the first call.
398*6777b538SAndroid Build Coastguard Worker cb.Run();
399*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, n);
400*6777b538SAndroid Build Coastguard Worker
401*6777b538SAndroid Build Coastguard Worker n = 0;
402*6777b538SAndroid Build Coastguard Worker cb.Run();
403*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, n);
404*6777b538SAndroid Build Coastguard Worker }
405*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,RepeatingCallbackBasicTest)406*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, RepeatingCallbackBasicTest) {
407*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int)> c0 = BindRepeating(&Sum, 1, 2, 4, 8, 16);
408*6777b538SAndroid Build Coastguard Worker
409*6777b538SAndroid Build Coastguard Worker // RepeatingCallback can run via a lvalue-reference.
410*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(63, c0.Run(32));
411*6777b538SAndroid Build Coastguard Worker
412*6777b538SAndroid Build Coastguard Worker // It is valid to call a RepeatingCallback more than once.
413*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(54, c0.Run(23));
414*6777b538SAndroid Build Coastguard Worker
415*6777b538SAndroid Build Coastguard Worker // BindRepeating can handle a RepeatingCallback as the target functor.
416*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> c1 = BindRepeating(c0, 11);
417*6777b538SAndroid Build Coastguard Worker
418*6777b538SAndroid Build Coastguard Worker // RepeatingCallback can run via a rvalue-reference.
419*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, std::move(c1).Run());
420*6777b538SAndroid Build Coastguard Worker
421*6777b538SAndroid Build Coastguard Worker // BindRepeating can handle a rvalue-reference of RepeatingCallback.
422*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(32, BindRepeating(std::move(c0), 1).Run());
423*6777b538SAndroid Build Coastguard Worker }
424*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OnceCallbackBasicTest)425*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OnceCallbackBasicTest) {
426*6777b538SAndroid Build Coastguard Worker OnceCallback<int(int)> c0 = BindOnce(&Sum, 1, 2, 4, 8, 16);
427*6777b538SAndroid Build Coastguard Worker
428*6777b538SAndroid Build Coastguard Worker // OnceCallback can run via a rvalue-reference.
429*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(63, std::move(c0).Run(32));
430*6777b538SAndroid Build Coastguard Worker
431*6777b538SAndroid Build Coastguard Worker // After running via the rvalue-reference, the value of the OnceCallback
432*6777b538SAndroid Build Coastguard Worker // is undefined. The implementation simply clears the instance after the
433*6777b538SAndroid Build Coastguard Worker // invocation.
434*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(c0.is_null());
435*6777b538SAndroid Build Coastguard Worker
436*6777b538SAndroid Build Coastguard Worker c0 = BindOnce(&Sum, 2, 3, 5, 7, 11);
437*6777b538SAndroid Build Coastguard Worker
438*6777b538SAndroid Build Coastguard Worker // BindOnce can handle a rvalue-reference of OnceCallback as the target
439*6777b538SAndroid Build Coastguard Worker // functor.
440*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> c1 = BindOnce(std::move(c0), 13);
441*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(41, std::move(c1).Run());
442*6777b538SAndroid Build Coastguard Worker
443*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int)> c2 = BindRepeating(&Sum, 2, 3, 5, 7, 11);
444*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(41, BindOnce(c2, 13).Run());
445*6777b538SAndroid Build Coastguard Worker }
446*6777b538SAndroid Build Coastguard Worker
447*6777b538SAndroid Build Coastguard Worker // IgnoreResult adapter test.
448*6777b538SAndroid Build Coastguard Worker // - Function with return value.
449*6777b538SAndroid Build Coastguard Worker // - Method with return value.
450*6777b538SAndroid Build Coastguard Worker // - Const Method with return.
451*6777b538SAndroid Build Coastguard Worker // - Method with return value bound to WeakPtr<>.
452*6777b538SAndroid Build Coastguard Worker // - Const Method with return bound to WeakPtr<>.
TEST_F(BindTest,IgnoreResultForRepeating)453*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, IgnoreResultForRepeating) {
454*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
455*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, AddRef()).Times(2);
456*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, Release()).Times(2);
457*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
458*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
459*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
460*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(no_ref_, IntMethod0()).WillOnce(Return(12));
461*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(no_ref_, IntConstMethod0()).WillOnce(Return(13));
462*6777b538SAndroid Build Coastguard Worker
463*6777b538SAndroid Build Coastguard Worker RepeatingClosure normal_func_cb = BindRepeating(IgnoreResult(&IntFunc0));
464*6777b538SAndroid Build Coastguard Worker normal_func_cb.Run();
465*6777b538SAndroid Build Coastguard Worker
466*6777b538SAndroid Build Coastguard Worker RepeatingClosure non_void_method_cb =
467*6777b538SAndroid Build Coastguard Worker BindRepeating(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
468*6777b538SAndroid Build Coastguard Worker non_void_method_cb.Run();
469*6777b538SAndroid Build Coastguard Worker
470*6777b538SAndroid Build Coastguard Worker RepeatingClosure non_void_const_method_cb =
471*6777b538SAndroid Build Coastguard Worker BindRepeating(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
472*6777b538SAndroid Build Coastguard Worker non_void_const_method_cb.Run();
473*6777b538SAndroid Build Coastguard Worker
474*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<NoRef> weak_factory(&no_ref_);
475*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
476*6777b538SAndroid Build Coastguard Worker
477*6777b538SAndroid Build Coastguard Worker RepeatingClosure non_void_weak_method_cb = BindRepeating(
478*6777b538SAndroid Build Coastguard Worker IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
479*6777b538SAndroid Build Coastguard Worker non_void_weak_method_cb.Run();
480*6777b538SAndroid Build Coastguard Worker
481*6777b538SAndroid Build Coastguard Worker RepeatingClosure non_void_weak_const_method_cb = BindRepeating(
482*6777b538SAndroid Build Coastguard Worker IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
483*6777b538SAndroid Build Coastguard Worker non_void_weak_const_method_cb.Run();
484*6777b538SAndroid Build Coastguard Worker
485*6777b538SAndroid Build Coastguard Worker weak_factory.InvalidateWeakPtrs();
486*6777b538SAndroid Build Coastguard Worker non_void_weak_const_method_cb.Run();
487*6777b538SAndroid Build Coastguard Worker non_void_weak_method_cb.Run();
488*6777b538SAndroid Build Coastguard Worker }
489*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,IgnoreResultForOnce)490*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, IgnoreResultForOnce) {
491*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(static_func_mock_, IntMethod0()).WillOnce(Return(1337));
492*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, AddRef()).Times(2);
493*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, Release()).Times(2);
494*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, HasAtLeastOneRef()).WillRepeatedly(Return(true));
495*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, IntMethod0()).WillOnce(Return(10));
496*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref_, IntConstMethod0()).WillOnce(Return(11));
497*6777b538SAndroid Build Coastguard Worker
498*6777b538SAndroid Build Coastguard Worker OnceClosure normal_func_cb = BindOnce(IgnoreResult(&IntFunc0));
499*6777b538SAndroid Build Coastguard Worker std::move(normal_func_cb).Run();
500*6777b538SAndroid Build Coastguard Worker
501*6777b538SAndroid Build Coastguard Worker OnceClosure non_void_method_cb =
502*6777b538SAndroid Build Coastguard Worker BindOnce(IgnoreResult(&HasRef::IntMethod0), &has_ref_);
503*6777b538SAndroid Build Coastguard Worker std::move(non_void_method_cb).Run();
504*6777b538SAndroid Build Coastguard Worker
505*6777b538SAndroid Build Coastguard Worker OnceClosure non_void_const_method_cb =
506*6777b538SAndroid Build Coastguard Worker BindOnce(IgnoreResult(&HasRef::IntConstMethod0), &has_ref_);
507*6777b538SAndroid Build Coastguard Worker std::move(non_void_const_method_cb).Run();
508*6777b538SAndroid Build Coastguard Worker
509*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<NoRef> weak_factory(&no_ref_);
510*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
511*6777b538SAndroid Build Coastguard Worker
512*6777b538SAndroid Build Coastguard Worker OnceClosure non_void_weak_method_cb =
513*6777b538SAndroid Build Coastguard Worker BindOnce(IgnoreResult(&NoRef::IntMethod0), weak_factory.GetWeakPtr());
514*6777b538SAndroid Build Coastguard Worker OnceClosure non_void_weak_const_method_cb = BindOnce(
515*6777b538SAndroid Build Coastguard Worker IgnoreResult(&NoRef::IntConstMethod0), weak_factory.GetWeakPtr());
516*6777b538SAndroid Build Coastguard Worker
517*6777b538SAndroid Build Coastguard Worker weak_factory.InvalidateWeakPtrs();
518*6777b538SAndroid Build Coastguard Worker std::move(non_void_weak_const_method_cb).Run();
519*6777b538SAndroid Build Coastguard Worker std::move(non_void_weak_method_cb).Run();
520*6777b538SAndroid Build Coastguard Worker }
521*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,IgnoreResultForRepeatingCallback)522*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, IgnoreResultForRepeatingCallback) {
523*6777b538SAndroid Build Coastguard Worker std::string s;
524*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int)> cb = BindRepeating(
525*6777b538SAndroid Build Coastguard Worker [](std::string* s, int i) {
526*6777b538SAndroid Build Coastguard Worker *s += "Run" + NumberToString(i);
527*6777b538SAndroid Build Coastguard Worker return 5;
528*6777b538SAndroid Build Coastguard Worker },
529*6777b538SAndroid Build Coastguard Worker &s);
530*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void(int)> noreturn = BindRepeating(IgnoreResult(cb));
531*6777b538SAndroid Build Coastguard Worker noreturn.Run(2);
532*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(s, "Run2");
533*6777b538SAndroid Build Coastguard Worker }
534*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,IgnoreResultForOnceCallback)535*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, IgnoreResultForOnceCallback) {
536*6777b538SAndroid Build Coastguard Worker std::string s;
537*6777b538SAndroid Build Coastguard Worker OnceCallback<int(int)> cb = BindOnce(
538*6777b538SAndroid Build Coastguard Worker [](std::string* s, int i) {
539*6777b538SAndroid Build Coastguard Worker *s += "Run" + NumberToString(i);
540*6777b538SAndroid Build Coastguard Worker return 5;
541*6777b538SAndroid Build Coastguard Worker },
542*6777b538SAndroid Build Coastguard Worker &s);
543*6777b538SAndroid Build Coastguard Worker OnceCallback<void(int)> noreturn = BindOnce(IgnoreResult(std::move(cb)));
544*6777b538SAndroid Build Coastguard Worker std::move(noreturn).Run(2);
545*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(s, "Run2");
546*6777b538SAndroid Build Coastguard Worker }
547*6777b538SAndroid Build Coastguard Worker
SetFromRef(int & ref)548*6777b538SAndroid Build Coastguard Worker void SetFromRef(int& ref) {
549*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ref, 1);
550*6777b538SAndroid Build Coastguard Worker ref = 2;
551*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ref, 2);
552*6777b538SAndroid Build Coastguard Worker }
553*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,BindOnceWithNonConstRef)554*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, BindOnceWithNonConstRef) {
555*6777b538SAndroid Build Coastguard Worker int v = 1;
556*6777b538SAndroid Build Coastguard Worker
557*6777b538SAndroid Build Coastguard Worker // Mutates `v` because it's not bound to callback instead it's forwarded by
558*6777b538SAndroid Build Coastguard Worker // Run().
559*6777b538SAndroid Build Coastguard Worker auto cb1 = BindOnce(SetFromRef);
560*6777b538SAndroid Build Coastguard Worker std::move(cb1).Run(v);
561*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 2);
562*6777b538SAndroid Build Coastguard Worker v = 1;
563*6777b538SAndroid Build Coastguard Worker
564*6777b538SAndroid Build Coastguard Worker // Mutates `v` through std::reference_wrapper bound to callback.
565*6777b538SAndroid Build Coastguard Worker auto cb2 = BindOnce(SetFromRef, std::ref(v));
566*6777b538SAndroid Build Coastguard Worker std::move(cb2).Run();
567*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 2);
568*6777b538SAndroid Build Coastguard Worker v = 1;
569*6777b538SAndroid Build Coastguard Worker
570*6777b538SAndroid Build Coastguard Worker // Everything past here following will make a copy of the argument. The copy
571*6777b538SAndroid Build Coastguard Worker // will be mutated and leave `v` unmodified.
572*6777b538SAndroid Build Coastguard Worker auto cb3 = BindOnce(SetFromRef, OwnedRef(v));
573*6777b538SAndroid Build Coastguard Worker std::move(cb3).Run();
574*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 1);
575*6777b538SAndroid Build Coastguard Worker
576*6777b538SAndroid Build Coastguard Worker int& ref = v;
577*6777b538SAndroid Build Coastguard Worker auto cb4 = BindOnce(SetFromRef, OwnedRef(ref));
578*6777b538SAndroid Build Coastguard Worker std::move(cb4).Run();
579*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 1);
580*6777b538SAndroid Build Coastguard Worker
581*6777b538SAndroid Build Coastguard Worker const int cv = 1;
582*6777b538SAndroid Build Coastguard Worker auto cb5 = BindOnce(SetFromRef, OwnedRef(cv));
583*6777b538SAndroid Build Coastguard Worker std::move(cb5).Run();
584*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(cv, 1);
585*6777b538SAndroid Build Coastguard Worker
586*6777b538SAndroid Build Coastguard Worker const int& cref = v;
587*6777b538SAndroid Build Coastguard Worker auto cb6 = BindOnce(SetFromRef, OwnedRef(cref));
588*6777b538SAndroid Build Coastguard Worker std::move(cb6).Run();
589*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(cref, 1);
590*6777b538SAndroid Build Coastguard Worker
591*6777b538SAndroid Build Coastguard Worker auto cb7 = BindOnce(SetFromRef, OwnedRef(1));
592*6777b538SAndroid Build Coastguard Worker std::move(cb7).Run();
593*6777b538SAndroid Build Coastguard Worker }
594*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,BindRepeatingWithNonConstRef)595*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, BindRepeatingWithNonConstRef) {
596*6777b538SAndroid Build Coastguard Worker int v = 1;
597*6777b538SAndroid Build Coastguard Worker
598*6777b538SAndroid Build Coastguard Worker // Mutates `v` because it's not bound to callback instead it's forwarded by
599*6777b538SAndroid Build Coastguard Worker // Run().
600*6777b538SAndroid Build Coastguard Worker auto cb1 = BindRepeating(SetFromRef);
601*6777b538SAndroid Build Coastguard Worker std::move(cb1).Run(v);
602*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 2);
603*6777b538SAndroid Build Coastguard Worker v = 1;
604*6777b538SAndroid Build Coastguard Worker
605*6777b538SAndroid Build Coastguard Worker // Mutates `v` through std::reference_wrapper bound to callback.
606*6777b538SAndroid Build Coastguard Worker auto cb2 = BindRepeating(SetFromRef, std::ref(v));
607*6777b538SAndroid Build Coastguard Worker std::move(cb2).Run();
608*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 2);
609*6777b538SAndroid Build Coastguard Worker v = 1;
610*6777b538SAndroid Build Coastguard Worker
611*6777b538SAndroid Build Coastguard Worker // Everything past here following will make a copy of the argument. The copy
612*6777b538SAndroid Build Coastguard Worker // will be mutated and leave `v` unmodified.
613*6777b538SAndroid Build Coastguard Worker auto cb3 = BindRepeating(SetFromRef, OwnedRef(v));
614*6777b538SAndroid Build Coastguard Worker std::move(cb3).Run();
615*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 1);
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard Worker int& ref = v;
618*6777b538SAndroid Build Coastguard Worker auto cb4 = BindRepeating(SetFromRef, OwnedRef(ref));
619*6777b538SAndroid Build Coastguard Worker std::move(cb4).Run();
620*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(v, 1);
621*6777b538SAndroid Build Coastguard Worker
622*6777b538SAndroid Build Coastguard Worker const int cv = 1;
623*6777b538SAndroid Build Coastguard Worker auto cb5 = BindRepeating(SetFromRef, OwnedRef(cv));
624*6777b538SAndroid Build Coastguard Worker std::move(cb5).Run();
625*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(cv, 1);
626*6777b538SAndroid Build Coastguard Worker
627*6777b538SAndroid Build Coastguard Worker const int& cref = v;
628*6777b538SAndroid Build Coastguard Worker auto cb6 = BindRepeating(SetFromRef, OwnedRef(cref));
629*6777b538SAndroid Build Coastguard Worker std::move(cb6).Run();
630*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(cref, 1);
631*6777b538SAndroid Build Coastguard Worker
632*6777b538SAndroid Build Coastguard Worker auto cb7 = BindRepeating(SetFromRef, OwnedRef(1));
633*6777b538SAndroid Build Coastguard Worker std::move(cb7).Run();
634*6777b538SAndroid Build Coastguard Worker }
635*6777b538SAndroid Build Coastguard Worker
636*6777b538SAndroid Build Coastguard Worker // Functions that take reference parameters.
637*6777b538SAndroid Build Coastguard Worker // - Forced reference parameter type still stores a copy.
638*6777b538SAndroid Build Coastguard Worker // - Forced const reference parameter type still stores a copy.
TEST_F(BindTest,ReferenceArgumentBindingForRepeating)639*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ReferenceArgumentBindingForRepeating) {
640*6777b538SAndroid Build Coastguard Worker int n = 1;
641*6777b538SAndroid Build Coastguard Worker int& ref_n = n;
642*6777b538SAndroid Build Coastguard Worker const int& const_ref_n = n;
643*6777b538SAndroid Build Coastguard Worker
644*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> ref_copies_cb = BindRepeating(&Identity, ref_n);
645*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n, ref_copies_cb.Run());
646*6777b538SAndroid Build Coastguard Worker n++;
647*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n - 1, ref_copies_cb.Run());
648*6777b538SAndroid Build Coastguard Worker
649*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> const_ref_copies_cb =
650*6777b538SAndroid Build Coastguard Worker BindRepeating(&Identity, const_ref_n);
651*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n, const_ref_copies_cb.Run());
652*6777b538SAndroid Build Coastguard Worker n++;
653*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n - 1, const_ref_copies_cb.Run());
654*6777b538SAndroid Build Coastguard Worker }
655*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,ReferenceArgumentBindingForOnce)656*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ReferenceArgumentBindingForOnce) {
657*6777b538SAndroid Build Coastguard Worker int n = 1;
658*6777b538SAndroid Build Coastguard Worker int& ref_n = n;
659*6777b538SAndroid Build Coastguard Worker const int& const_ref_n = n;
660*6777b538SAndroid Build Coastguard Worker
661*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> ref_copies_cb = BindOnce(&Identity, ref_n);
662*6777b538SAndroid Build Coastguard Worker n++;
663*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n - 1, std::move(ref_copies_cb).Run());
664*6777b538SAndroid Build Coastguard Worker
665*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> const_ref_copies_cb = BindOnce(&Identity, const_ref_n);
666*6777b538SAndroid Build Coastguard Worker n++;
667*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n - 1, std::move(const_ref_copies_cb).Run());
668*6777b538SAndroid Build Coastguard Worker }
669*6777b538SAndroid Build Coastguard Worker
670*6777b538SAndroid Build Coastguard Worker // Check that we can pass in arrays and have them be stored as a pointer.
671*6777b538SAndroid Build Coastguard Worker // - Array of values stores a pointer.
672*6777b538SAndroid Build Coastguard Worker // - Array of const values stores a pointer.
TEST_F(BindTest,ArrayArgumentBindingForRepeating)673*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ArrayArgumentBindingForRepeating) {
674*6777b538SAndroid Build Coastguard Worker int array[4] = {1, 1, 1, 1};
675*6777b538SAndroid Build Coastguard Worker const int(*const_array_ptr)[4] = &array;
676*6777b538SAndroid Build Coastguard Worker
677*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> array_cb = BindRepeating(&ArrayGet, array, 1);
678*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, array_cb.Run());
679*6777b538SAndroid Build Coastguard Worker
680*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> const_array_cb =
681*6777b538SAndroid Build Coastguard Worker BindRepeating(&ArrayGet, *const_array_ptr, 1);
682*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, const_array_cb.Run());
683*6777b538SAndroid Build Coastguard Worker
684*6777b538SAndroid Build Coastguard Worker array[1] = 3;
685*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, array_cb.Run());
686*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, const_array_cb.Run());
687*6777b538SAndroid Build Coastguard Worker }
688*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,ArrayArgumentBindingForOnce)689*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ArrayArgumentBindingForOnce) {
690*6777b538SAndroid Build Coastguard Worker int array[4] = {1, 1, 1, 1};
691*6777b538SAndroid Build Coastguard Worker const int(*const_array_ptr)[4] = &array;
692*6777b538SAndroid Build Coastguard Worker
693*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> array_cb = BindOnce(&ArrayGet, array, 1);
694*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> const_array_cb = BindOnce(&ArrayGet, *const_array_ptr, 1);
695*6777b538SAndroid Build Coastguard Worker
696*6777b538SAndroid Build Coastguard Worker array[1] = 3;
697*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, std::move(array_cb).Run());
698*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, std::move(const_array_cb).Run());
699*6777b538SAndroid Build Coastguard Worker }
700*6777b538SAndroid Build Coastguard Worker
701*6777b538SAndroid Build Coastguard Worker // WeakPtr() support.
702*6777b538SAndroid Build Coastguard Worker // - Method bound to WeakPtr<> to non-const object.
703*6777b538SAndroid Build Coastguard Worker // - Const method bound to WeakPtr<> to non-const object.
704*6777b538SAndroid Build Coastguard Worker // - Const method bound to WeakPtr<> to const object.
705*6777b538SAndroid Build Coastguard Worker // - Normal Function with WeakPtr<> as P1 can have return type and is
706*6777b538SAndroid Build Coastguard Worker // not canceled.
TEST_F(BindTest,WeakPtrForRepeating)707*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, WeakPtrForRepeating) {
708*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(no_ref_, VoidMethod0());
709*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(no_ref_, VoidConstMethod0()).Times(2);
710*6777b538SAndroid Build Coastguard Worker
711*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<NoRef> weak_factory(&no_ref_);
712*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
713*6777b538SAndroid Build Coastguard Worker
714*6777b538SAndroid Build Coastguard Worker RepeatingClosure method_cb =
715*6777b538SAndroid Build Coastguard Worker BindRepeating(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
716*6777b538SAndroid Build Coastguard Worker method_cb.Run();
717*6777b538SAndroid Build Coastguard Worker
718*6777b538SAndroid Build Coastguard Worker RepeatingClosure const_method_cb =
719*6777b538SAndroid Build Coastguard Worker BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
720*6777b538SAndroid Build Coastguard Worker const_method_cb.Run();
721*6777b538SAndroid Build Coastguard Worker
722*6777b538SAndroid Build Coastguard Worker RepeatingClosure const_method_const_ptr_cb =
723*6777b538SAndroid Build Coastguard Worker BindRepeating(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
724*6777b538SAndroid Build Coastguard Worker const_method_const_ptr_cb.Run();
725*6777b538SAndroid Build Coastguard Worker
726*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int(int)> normal_func_cb =
727*6777b538SAndroid Build Coastguard Worker BindRepeating(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
728*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, normal_func_cb.Run(1));
729*6777b538SAndroid Build Coastguard Worker
730*6777b538SAndroid Build Coastguard Worker weak_factory.InvalidateWeakPtrs();
731*6777b538SAndroid Build Coastguard Worker const_weak_factory.InvalidateWeakPtrs();
732*6777b538SAndroid Build Coastguard Worker
733*6777b538SAndroid Build Coastguard Worker method_cb.Run();
734*6777b538SAndroid Build Coastguard Worker const_method_cb.Run();
735*6777b538SAndroid Build Coastguard Worker const_method_const_ptr_cb.Run();
736*6777b538SAndroid Build Coastguard Worker
737*6777b538SAndroid Build Coastguard Worker // Still runs even after the pointers are invalidated.
738*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, normal_func_cb.Run(2));
739*6777b538SAndroid Build Coastguard Worker }
740*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,WeakPtrForOnce)741*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, WeakPtrForOnce) {
742*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<NoRef> weak_factory(&no_ref_);
743*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<const NoRef> const_weak_factory(const_no_ref_ptr_.get());
744*6777b538SAndroid Build Coastguard Worker
745*6777b538SAndroid Build Coastguard Worker OnceClosure method_cb =
746*6777b538SAndroid Build Coastguard Worker BindOnce(&NoRef::VoidMethod0, weak_factory.GetWeakPtr());
747*6777b538SAndroid Build Coastguard Worker OnceClosure const_method_cb =
748*6777b538SAndroid Build Coastguard Worker BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
749*6777b538SAndroid Build Coastguard Worker OnceClosure const_method_const_ptr_cb =
750*6777b538SAndroid Build Coastguard Worker BindOnce(&NoRef::VoidConstMethod0, const_weak_factory.GetWeakPtr());
751*6777b538SAndroid Build Coastguard Worker OnceCallback<int(int)> normal_func_cb =
752*6777b538SAndroid Build Coastguard Worker BindOnce(&FunctionWithWeakFirstParam, weak_factory.GetWeakPtr());
753*6777b538SAndroid Build Coastguard Worker
754*6777b538SAndroid Build Coastguard Worker weak_factory.InvalidateWeakPtrs();
755*6777b538SAndroid Build Coastguard Worker const_weak_factory.InvalidateWeakPtrs();
756*6777b538SAndroid Build Coastguard Worker
757*6777b538SAndroid Build Coastguard Worker std::move(method_cb).Run();
758*6777b538SAndroid Build Coastguard Worker std::move(const_method_cb).Run();
759*6777b538SAndroid Build Coastguard Worker std::move(const_method_const_ptr_cb).Run();
760*6777b538SAndroid Build Coastguard Worker
761*6777b538SAndroid Build Coastguard Worker // Still runs even after the pointers are invalidated.
762*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, std::move(normal_func_cb).Run(2));
763*6777b538SAndroid Build Coastguard Worker }
764*6777b538SAndroid Build Coastguard Worker
765*6777b538SAndroid Build Coastguard Worker // std::cref() wrapper support.
766*6777b538SAndroid Build Coastguard Worker // - Binding w/o std::cref takes a copy.
767*6777b538SAndroid Build Coastguard Worker // - Binding a std::cref takes a reference.
768*6777b538SAndroid Build Coastguard Worker // - Binding std::cref to a function std::cref does not copy on invoke.
TEST_F(BindTest,StdCrefForRepeating)769*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, StdCrefForRepeating) {
770*6777b538SAndroid Build Coastguard Worker int n = 1;
771*6777b538SAndroid Build Coastguard Worker
772*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> copy_cb = BindRepeating(&Identity, n);
773*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> const_ref_cb =
774*6777b538SAndroid Build Coastguard Worker BindRepeating(&Identity, std::cref(n));
775*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n, copy_cb.Run());
776*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n, const_ref_cb.Run());
777*6777b538SAndroid Build Coastguard Worker n++;
778*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n - 1, copy_cb.Run());
779*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n, const_ref_cb.Run());
780*6777b538SAndroid Build Coastguard Worker
781*6777b538SAndroid Build Coastguard Worker int copies = 0;
782*6777b538SAndroid Build Coastguard Worker int assigns = 0;
783*6777b538SAndroid Build Coastguard Worker int move_constructs = 0;
784*6777b538SAndroid Build Coastguard Worker int move_assigns = 0;
785*6777b538SAndroid Build Coastguard Worker CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
786*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> all_const_ref_cb =
787*6777b538SAndroid Build Coastguard Worker BindRepeating(&GetCopies, std::cref(counter));
788*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, all_const_ref_cb.Run());
789*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, copies);
790*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
791*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_constructs);
792*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
793*6777b538SAndroid Build Coastguard Worker }
794*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,StdCrefForOnce)795*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, StdCrefForOnce) {
796*6777b538SAndroid Build Coastguard Worker int n = 1;
797*6777b538SAndroid Build Coastguard Worker
798*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> copy_cb = BindOnce(&Identity, n);
799*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> const_ref_cb = BindOnce(&Identity, std::cref(n));
800*6777b538SAndroid Build Coastguard Worker n++;
801*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n - 1, std::move(copy_cb).Run());
802*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n, std::move(const_ref_cb).Run());
803*6777b538SAndroid Build Coastguard Worker
804*6777b538SAndroid Build Coastguard Worker int copies = 0;
805*6777b538SAndroid Build Coastguard Worker int assigns = 0;
806*6777b538SAndroid Build Coastguard Worker int move_constructs = 0;
807*6777b538SAndroid Build Coastguard Worker int move_assigns = 0;
808*6777b538SAndroid Build Coastguard Worker CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
809*6777b538SAndroid Build Coastguard Worker OnceCallback<int()> all_const_ref_cb =
810*6777b538SAndroid Build Coastguard Worker BindOnce(&GetCopies, std::cref(counter));
811*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, std::move(all_const_ref_cb).Run());
812*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, copies);
813*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
814*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_constructs);
815*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
816*6777b538SAndroid Build Coastguard Worker }
817*6777b538SAndroid Build Coastguard Worker
818*6777b538SAndroid Build Coastguard Worker // Test Owned() support.
TEST_F(BindTest,OwnedForRepeatingRawPtr)819*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OwnedForRepeatingRawPtr) {
820*6777b538SAndroid Build Coastguard Worker int deletes = 0;
821*6777b538SAndroid Build Coastguard Worker DeleteCounter* counter = new DeleteCounter(&deletes);
822*6777b538SAndroid Build Coastguard Worker
823*6777b538SAndroid Build Coastguard Worker // If we don't capture, delete happens on Callback destruction/reset.
824*6777b538SAndroid Build Coastguard Worker // return the same value.
825*6777b538SAndroid Build Coastguard Worker RepeatingCallback<DeleteCounter*()> no_capture_cb =
826*6777b538SAndroid Build Coastguard Worker BindRepeating(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
827*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(counter, no_capture_cb.Run());
828*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(counter, no_capture_cb.Run());
829*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
830*6777b538SAndroid Build Coastguard Worker no_capture_cb.Reset(); // This should trigger a delete.
831*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
832*6777b538SAndroid Build Coastguard Worker
833*6777b538SAndroid Build Coastguard Worker deletes = 0;
834*6777b538SAndroid Build Coastguard Worker counter = new DeleteCounter(&deletes);
835*6777b538SAndroid Build Coastguard Worker RepeatingClosure own_object_cb =
836*6777b538SAndroid Build Coastguard Worker BindRepeating(&DeleteCounter::VoidMethod0, Owned(counter));
837*6777b538SAndroid Build Coastguard Worker own_object_cb.Run();
838*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
839*6777b538SAndroid Build Coastguard Worker own_object_cb.Reset();
840*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
841*6777b538SAndroid Build Coastguard Worker }
842*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OwnedForOnceRawPtr)843*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OwnedForOnceRawPtr) {
844*6777b538SAndroid Build Coastguard Worker int deletes = 0;
845*6777b538SAndroid Build Coastguard Worker DeleteCounter* counter = new DeleteCounter(&deletes);
846*6777b538SAndroid Build Coastguard Worker
847*6777b538SAndroid Build Coastguard Worker // If we don't capture, delete happens on Callback destruction/reset.
848*6777b538SAndroid Build Coastguard Worker // return the same value.
849*6777b538SAndroid Build Coastguard Worker OnceCallback<DeleteCounter*()> no_capture_cb =
850*6777b538SAndroid Build Coastguard Worker BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(counter));
851*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
852*6777b538SAndroid Build Coastguard Worker no_capture_cb.Reset(); // This should trigger a delete.
853*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
854*6777b538SAndroid Build Coastguard Worker
855*6777b538SAndroid Build Coastguard Worker deletes = 0;
856*6777b538SAndroid Build Coastguard Worker counter = new DeleteCounter(&deletes);
857*6777b538SAndroid Build Coastguard Worker OnceClosure own_object_cb =
858*6777b538SAndroid Build Coastguard Worker BindOnce(&DeleteCounter::VoidMethod0, Owned(counter));
859*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
860*6777b538SAndroid Build Coastguard Worker own_object_cb.Reset();
861*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
862*6777b538SAndroid Build Coastguard Worker }
863*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OwnedForRepeatingUniquePtr)864*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OwnedForRepeatingUniquePtr) {
865*6777b538SAndroid Build Coastguard Worker int deletes = 0;
866*6777b538SAndroid Build Coastguard Worker auto counter = std::make_unique<DeleteCounter>(&deletes);
867*6777b538SAndroid Build Coastguard Worker DeleteCounter* raw_counter = counter.get();
868*6777b538SAndroid Build Coastguard Worker
869*6777b538SAndroid Build Coastguard Worker // If we don't capture, delete happens on Callback destruction/reset.
870*6777b538SAndroid Build Coastguard Worker // return the same value.
871*6777b538SAndroid Build Coastguard Worker RepeatingCallback<DeleteCounter*()> no_capture_cb = BindRepeating(
872*6777b538SAndroid Build Coastguard Worker &PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
873*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(raw_counter, no_capture_cb.Run());
874*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(raw_counter, no_capture_cb.Run());
875*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
876*6777b538SAndroid Build Coastguard Worker no_capture_cb.Reset(); // This should trigger a delete.
877*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
878*6777b538SAndroid Build Coastguard Worker
879*6777b538SAndroid Build Coastguard Worker deletes = 0;
880*6777b538SAndroid Build Coastguard Worker counter = std::make_unique<DeleteCounter>(&deletes);
881*6777b538SAndroid Build Coastguard Worker RepeatingClosure own_object_cb =
882*6777b538SAndroid Build Coastguard Worker BindRepeating(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
883*6777b538SAndroid Build Coastguard Worker own_object_cb.Run();
884*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
885*6777b538SAndroid Build Coastguard Worker own_object_cb.Reset();
886*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
887*6777b538SAndroid Build Coastguard Worker }
888*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OwnedForOnceUniquePtr)889*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OwnedForOnceUniquePtr) {
890*6777b538SAndroid Build Coastguard Worker int deletes = 0;
891*6777b538SAndroid Build Coastguard Worker auto counter = std::make_unique<DeleteCounter>(&deletes);
892*6777b538SAndroid Build Coastguard Worker
893*6777b538SAndroid Build Coastguard Worker // If we don't capture, delete happens on Callback destruction/reset.
894*6777b538SAndroid Build Coastguard Worker // return the same value.
895*6777b538SAndroid Build Coastguard Worker OnceCallback<DeleteCounter*()> no_capture_cb =
896*6777b538SAndroid Build Coastguard Worker BindOnce(&PolymorphicIdentity<DeleteCounter*>, Owned(std::move(counter)));
897*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
898*6777b538SAndroid Build Coastguard Worker no_capture_cb.Reset(); // This should trigger a delete.
899*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
900*6777b538SAndroid Build Coastguard Worker
901*6777b538SAndroid Build Coastguard Worker deletes = 0;
902*6777b538SAndroid Build Coastguard Worker counter = std::make_unique<DeleteCounter>(&deletes);
903*6777b538SAndroid Build Coastguard Worker OnceClosure own_object_cb =
904*6777b538SAndroid Build Coastguard Worker BindOnce(&DeleteCounter::VoidMethod0, Owned(std::move(counter)));
905*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
906*6777b538SAndroid Build Coastguard Worker own_object_cb.Reset();
907*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
908*6777b538SAndroid Build Coastguard Worker }
909*6777b538SAndroid Build Coastguard Worker
910*6777b538SAndroid Build Coastguard Worker // Tests OwnedRef
TEST_F(BindTest,OwnedRefForCounter)911*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OwnedRefForCounter) {
912*6777b538SAndroid Build Coastguard Worker int counter = 0;
913*6777b538SAndroid Build Coastguard Worker RepeatingCallback<int()> counter_callback =
914*6777b538SAndroid Build Coastguard Worker BindRepeating([](int& counter) { return ++counter; }, OwnedRef(counter));
915*6777b538SAndroid Build Coastguard Worker
916*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, counter_callback.Run());
917*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, counter_callback.Run());
918*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, counter_callback.Run());
919*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, counter_callback.Run());
920*6777b538SAndroid Build Coastguard Worker
921*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, counter); // counter should remain unchanged.
922*6777b538SAndroid Build Coastguard Worker }
923*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OwnedRefForIgnoringArguments)924*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OwnedRefForIgnoringArguments) {
925*6777b538SAndroid Build Coastguard Worker OnceCallback<std::string(std::string)> echo_callback =
926*6777b538SAndroid Build Coastguard Worker BindOnce([](int& ignore, std::string s) { return s; }, OwnedRef(0));
927*6777b538SAndroid Build Coastguard Worker
928*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Hello World", std::move(echo_callback).Run("Hello World"));
929*6777b538SAndroid Build Coastguard Worker }
930*6777b538SAndroid Build Coastguard Worker
931*6777b538SAndroid Build Coastguard Worker template <typename T>
932*6777b538SAndroid Build Coastguard Worker class BindVariantsTest : public ::testing::Test {};
933*6777b538SAndroid Build Coastguard Worker
934*6777b538SAndroid Build Coastguard Worker struct RepeatingTestConfig {
935*6777b538SAndroid Build Coastguard Worker template <typename Signature>
936*6777b538SAndroid Build Coastguard Worker using CallbackType = RepeatingCallback<Signature>;
937*6777b538SAndroid Build Coastguard Worker using ClosureType = RepeatingClosure;
938*6777b538SAndroid Build Coastguard Worker
939*6777b538SAndroid Build Coastguard Worker template <typename F, typename... Args>
Bindbase::__anon8a4af9fd0111::RepeatingTestConfig940*6777b538SAndroid Build Coastguard Worker static auto Bind(F&& f, Args&&... args) {
941*6777b538SAndroid Build Coastguard Worker return BindRepeating(std::forward<F>(f), std::forward<Args>(args)...);
942*6777b538SAndroid Build Coastguard Worker }
943*6777b538SAndroid Build Coastguard Worker };
944*6777b538SAndroid Build Coastguard Worker
945*6777b538SAndroid Build Coastguard Worker struct OnceTestConfig {
946*6777b538SAndroid Build Coastguard Worker template <typename Signature>
947*6777b538SAndroid Build Coastguard Worker using CallbackType = OnceCallback<Signature>;
948*6777b538SAndroid Build Coastguard Worker using ClosureType = OnceClosure;
949*6777b538SAndroid Build Coastguard Worker
950*6777b538SAndroid Build Coastguard Worker template <typename F, typename... Args>
Bindbase::__anon8a4af9fd0111::OnceTestConfig951*6777b538SAndroid Build Coastguard Worker static auto Bind(F&& f, Args&&... args) {
952*6777b538SAndroid Build Coastguard Worker return BindOnce(std::forward<F>(f), std::forward<Args>(args)...);
953*6777b538SAndroid Build Coastguard Worker }
954*6777b538SAndroid Build Coastguard Worker };
955*6777b538SAndroid Build Coastguard Worker
956*6777b538SAndroid Build Coastguard Worker using BindVariantsTestConfig =
957*6777b538SAndroid Build Coastguard Worker ::testing::Types<RepeatingTestConfig, OnceTestConfig>;
958*6777b538SAndroid Build Coastguard Worker TYPED_TEST_SUITE(BindVariantsTest, BindVariantsTestConfig);
959*6777b538SAndroid Build Coastguard Worker
960*6777b538SAndroid Build Coastguard Worker template <typename TypeParam, typename Signature>
961*6777b538SAndroid Build Coastguard Worker using CallbackType = typename TypeParam::template CallbackType<Signature>;
962*6777b538SAndroid Build Coastguard Worker
963*6777b538SAndroid Build Coastguard Worker // Function type support.
964*6777b538SAndroid Build Coastguard Worker // - Normal function.
965*6777b538SAndroid Build Coastguard Worker // - Normal function bound with non-refcounted first argument.
966*6777b538SAndroid Build Coastguard Worker // - Method bound to non-const object.
967*6777b538SAndroid Build Coastguard Worker // - Method bound to scoped_refptr.
968*6777b538SAndroid Build Coastguard Worker // - Const method bound to non-const object.
969*6777b538SAndroid Build Coastguard Worker // - Const method bound to const object.
970*6777b538SAndroid Build Coastguard Worker // - Derived classes can be used with pointers to non-virtual base functions.
971*6777b538SAndroid Build Coastguard Worker // - Derived classes can be used with pointers to virtual base functions (and
972*6777b538SAndroid Build Coastguard Worker // preserve virtual dispatch).
TYPED_TEST(BindVariantsTest,FunctionTypeSupport)973*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, FunctionTypeSupport) {
974*6777b538SAndroid Build Coastguard Worker using ClosureType = typename TypeParam::ClosureType;
975*6777b538SAndroid Build Coastguard Worker
976*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref;
977*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef> no_ref;
978*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef> static_func_mock;
979*6777b538SAndroid Build Coastguard Worker const HasRef* const_has_ref_ptr = &has_ref;
980*6777b538SAndroid Build Coastguard Worker g_func_mock_ptr = &static_func_mock;
981*6777b538SAndroid Build Coastguard Worker
982*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(static_func_mock, VoidMethod0());
983*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, AddRef()).Times(4);
984*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, Release()).Times(4);
985*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
986*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, VoidMethod0()).Times(2);
987*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, VoidConstMethod0()).Times(2);
988*6777b538SAndroid Build Coastguard Worker
989*6777b538SAndroid Build Coastguard Worker ClosureType normal_cb = TypeParam::Bind(&VoidFunc0);
990*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, NoRef*()> normal_non_refcounted_cb =
991*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&PolymorphicIdentity<NoRef*>, &no_ref);
992*6777b538SAndroid Build Coastguard Worker std::move(normal_cb).Run();
993*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(&no_ref, std::move(normal_non_refcounted_cb).Run());
994*6777b538SAndroid Build Coastguard Worker
995*6777b538SAndroid Build Coastguard Worker ClosureType method_cb = TypeParam::Bind(&HasRef::VoidMethod0, &has_ref);
996*6777b538SAndroid Build Coastguard Worker ClosureType method_refptr_cb =
997*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::VoidMethod0, WrapRefCounted(&has_ref));
998*6777b538SAndroid Build Coastguard Worker ClosureType const_method_nonconst_obj_cb =
999*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::VoidConstMethod0, &has_ref);
1000*6777b538SAndroid Build Coastguard Worker ClosureType const_method_const_obj_cb =
1001*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::VoidConstMethod0, const_has_ref_ptr);
1002*6777b538SAndroid Build Coastguard Worker std::move(method_cb).Run();
1003*6777b538SAndroid Build Coastguard Worker std::move(method_refptr_cb).Run();
1004*6777b538SAndroid Build Coastguard Worker std::move(const_method_nonconst_obj_cb).Run();
1005*6777b538SAndroid Build Coastguard Worker std::move(const_method_const_obj_cb).Run();
1006*6777b538SAndroid Build Coastguard Worker
1007*6777b538SAndroid Build Coastguard Worker Child child;
1008*6777b538SAndroid Build Coastguard Worker child.value = 0;
1009*6777b538SAndroid Build Coastguard Worker ClosureType virtual_set_cb = TypeParam::Bind(&Parent::VirtualSet, &child);
1010*6777b538SAndroid Build Coastguard Worker std::move(virtual_set_cb).Run();
1011*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kChildValue, child.value);
1012*6777b538SAndroid Build Coastguard Worker
1013*6777b538SAndroid Build Coastguard Worker child.value = 0;
1014*6777b538SAndroid Build Coastguard Worker ClosureType non_virtual_set_cb =
1015*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&Parent::NonVirtualSet, &child);
1016*6777b538SAndroid Build Coastguard Worker std::move(non_virtual_set_cb).Run();
1017*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kParentValue, child.value);
1018*6777b538SAndroid Build Coastguard Worker }
1019*6777b538SAndroid Build Coastguard Worker
1020*6777b538SAndroid Build Coastguard Worker // Return value support.
1021*6777b538SAndroid Build Coastguard Worker // - Function with return value.
1022*6777b538SAndroid Build Coastguard Worker // - Method with return value.
1023*6777b538SAndroid Build Coastguard Worker // - Const method with return value.
1024*6777b538SAndroid Build Coastguard Worker // - Move-only return value.
TYPED_TEST(BindVariantsTest,ReturnValues)1025*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, ReturnValues) {
1026*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef> static_func_mock;
1027*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref;
1028*6777b538SAndroid Build Coastguard Worker g_func_mock_ptr = &static_func_mock;
1029*6777b538SAndroid Build Coastguard Worker const HasRef* const_has_ref_ptr = &has_ref;
1030*6777b538SAndroid Build Coastguard Worker
1031*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(static_func_mock, IntMethod0()).WillOnce(Return(1337));
1032*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, AddRef()).Times(4);
1033*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, Release()).Times(4);
1034*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1035*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, IntMethod0()).WillOnce(Return(31337));
1036*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, IntConstMethod0())
1037*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(41337))
1038*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(51337));
1039*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, UniquePtrMethod0())
1040*6777b538SAndroid Build Coastguard Worker .WillOnce(Return(ByMove(std::make_unique<int>(42))));
1041*6777b538SAndroid Build Coastguard Worker
1042*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, int()> normal_cb = TypeParam::Bind(&IntFunc0);
1043*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, int()> method_cb =
1044*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::IntMethod0, &has_ref);
1045*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, int()> const_method_nonconst_obj_cb =
1046*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::IntConstMethod0, &has_ref);
1047*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, int()> const_method_const_obj_cb =
1048*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::IntConstMethod0, const_has_ref_ptr);
1049*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, std::unique_ptr<int>()> move_only_rv_cb =
1050*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::UniquePtrMethod0, &has_ref);
1051*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1337, std::move(normal_cb).Run());
1052*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(31337, std::move(method_cb).Run());
1053*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(41337, std::move(const_method_nonconst_obj_cb).Run());
1054*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(51337, std::move(const_method_const_obj_cb).Run());
1055*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, *std::move(move_only_rv_cb).Run());
1056*6777b538SAndroid Build Coastguard Worker }
1057*6777b538SAndroid Build Coastguard Worker
1058*6777b538SAndroid Build Coastguard Worker // Argument binding tests.
1059*6777b538SAndroid Build Coastguard Worker // - Argument binding to primitive.
1060*6777b538SAndroid Build Coastguard Worker // - Argument binding to primitive pointer.
1061*6777b538SAndroid Build Coastguard Worker // - Argument binding to a literal integer.
1062*6777b538SAndroid Build Coastguard Worker // - Argument binding to a literal string.
1063*6777b538SAndroid Build Coastguard Worker // - Argument binding with template function.
1064*6777b538SAndroid Build Coastguard Worker // - Argument binding to an object.
1065*6777b538SAndroid Build Coastguard Worker // - Argument binding to pointer to incomplete type.
1066*6777b538SAndroid Build Coastguard Worker // - Argument gets type converted.
1067*6777b538SAndroid Build Coastguard Worker // - Pointer argument gets converted.
1068*6777b538SAndroid Build Coastguard Worker // - Const Reference forces conversion.
TYPED_TEST(BindVariantsTest,ArgumentBinding)1069*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, ArgumentBinding) {
1070*6777b538SAndroid Build Coastguard Worker int n = 2;
1071*6777b538SAndroid Build Coastguard Worker
1072*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(n, TypeParam::Bind(&Identity, n).Run());
1073*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(&n, TypeParam::Bind(&PolymorphicIdentity<int*>, &n).Run());
1074*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, TypeParam::Bind(&Identity, 3).Run());
1075*6777b538SAndroid Build Coastguard Worker EXPECT_STREQ("hi", TypeParam::Bind(&CStringIdentity, "hi").Run());
1076*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, TypeParam::Bind(&PolymorphicIdentity<int>, 4).Run());
1077*6777b538SAndroid Build Coastguard Worker
1078*6777b538SAndroid Build Coastguard Worker NoRefParent p;
1079*6777b538SAndroid Build Coastguard Worker p.value = 5;
1080*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5, TypeParam::Bind(&UnwrapNoRefParent, p).Run());
1081*6777b538SAndroid Build Coastguard Worker
1082*6777b538SAndroid Build Coastguard Worker NoRefChild c;
1083*6777b538SAndroid Build Coastguard Worker c.value = 6;
1084*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(6, TypeParam::Bind(&UnwrapNoRefParent, c).Run());
1085*6777b538SAndroid Build Coastguard Worker
1086*6777b538SAndroid Build Coastguard Worker c.value = 7;
1087*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(7, TypeParam::Bind(&UnwrapNoRefParentPtr, &c).Run());
1088*6777b538SAndroid Build Coastguard Worker
1089*6777b538SAndroid Build Coastguard Worker c.value = 8;
1090*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(8, TypeParam::Bind(&UnwrapNoRefParentConstRef, c).Run());
1091*6777b538SAndroid Build Coastguard Worker }
1092*6777b538SAndroid Build Coastguard Worker
1093*6777b538SAndroid Build Coastguard Worker // Unbound argument type support tests.
1094*6777b538SAndroid Build Coastguard Worker // - Unbound value.
1095*6777b538SAndroid Build Coastguard Worker // - Unbound pointer.
1096*6777b538SAndroid Build Coastguard Worker // - Unbound reference.
1097*6777b538SAndroid Build Coastguard Worker // - Unbound const reference.
1098*6777b538SAndroid Build Coastguard Worker // - Unbound unsized array.
1099*6777b538SAndroid Build Coastguard Worker // - Unbound sized array.
1100*6777b538SAndroid Build Coastguard Worker // - Unbound array-of-arrays.
TYPED_TEST(BindVariantsTest,UnboundArgumentTypeSupport)1101*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, UnboundArgumentTypeSupport) {
1102*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int)> unbound_value_cb =
1103*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<int>::Run);
1104*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int*)> unbound_pointer_cb =
1105*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<int*>::Run);
1106*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int&)> unbound_ref_cb =
1107*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<int&>::Run);
1108*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(const int&)> unbound_const_ref_cb =
1109*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<const int&>::Run);
1110*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int[])> unbound_unsized_array_cb =
1111*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<int[]>::Run);
1112*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int[2])> unbound_sized_array_cb =
1113*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<int[2]>::Run);
1114*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int[][2])> unbound_array_of_arrays_cb =
1115*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<int[][2]>::Run);
1116*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int&)> unbound_ref_with_bound_arg =
1117*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&VoidPolymorphic<int, int&>::Run, 1);
1118*6777b538SAndroid Build Coastguard Worker }
1119*6777b538SAndroid Build Coastguard Worker
1120*6777b538SAndroid Build Coastguard Worker // Function with unbound reference parameter.
1121*6777b538SAndroid Build Coastguard Worker // - Original parameter is modified by callback.
TYPED_TEST(BindVariantsTest,UnboundReferenceSupport)1122*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, UnboundReferenceSupport) {
1123*6777b538SAndroid Build Coastguard Worker int n = 0;
1124*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, void(int&)> unbound_ref_cb =
1125*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&RefArgSet);
1126*6777b538SAndroid Build Coastguard Worker std::move(unbound_ref_cb).Run(n);
1127*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, n);
1128*6777b538SAndroid Build Coastguard Worker }
1129*6777b538SAndroid Build Coastguard Worker
1130*6777b538SAndroid Build Coastguard Worker // Unretained() wrapper support.
1131*6777b538SAndroid Build Coastguard Worker // - Method bound to Unretained() non-const object.
1132*6777b538SAndroid Build Coastguard Worker // - Const method bound to Unretained() non-const object.
1133*6777b538SAndroid Build Coastguard Worker // - Const method bound to Unretained() const object.
TYPED_TEST(BindVariantsTest,Unretained)1134*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, Unretained) {
1135*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef> no_ref;
1136*6777b538SAndroid Build Coastguard Worker const NoRef* const_no_ref_ptr = &no_ref;
1137*6777b538SAndroid Build Coastguard Worker
1138*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(no_ref, VoidMethod0());
1139*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(no_ref, VoidConstMethod0()).Times(2);
1140*6777b538SAndroid Build Coastguard Worker
1141*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&NoRef::VoidMethod0, Unretained(&no_ref)).Run();
1142*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(&no_ref)).Run();
1143*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&NoRef::VoidConstMethod0, Unretained(const_no_ref_ptr)).Run();
1144*6777b538SAndroid Build Coastguard Worker }
1145*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindVariantsTest,ScopedRefptr)1146*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, ScopedRefptr) {
1147*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref;
1148*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, AddRef()).Times(1);
1149*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, Release()).Times(1);
1150*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1151*6777b538SAndroid Build Coastguard Worker
1152*6777b538SAndroid Build Coastguard Worker const scoped_refptr<HasRef> refptr(&has_ref);
1153*6777b538SAndroid Build Coastguard Worker CallbackType<TypeParam, int()> scoped_refptr_const_ref_cb = TypeParam::Bind(
1154*6777b538SAndroid Build Coastguard Worker &FunctionWithScopedRefptrFirstParam, std::cref(refptr), 1);
1155*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, std::move(scoped_refptr_const_ref_cb).Run());
1156*6777b538SAndroid Build Coastguard Worker }
1157*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindVariantsTest,UniquePtrReceiver)1158*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, UniquePtrReceiver) {
1159*6777b538SAndroid Build Coastguard Worker std::unique_ptr<StrictMock<NoRef>> no_ref(new StrictMock<NoRef>);
1160*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(*no_ref, VoidMethod0()).Times(1);
1161*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&NoRef::VoidMethod0, std::move(no_ref)).Run();
1162*6777b538SAndroid Build Coastguard Worker }
1163*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindVariantsTest,ImplicitRefPtrReceiver)1164*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, ImplicitRefPtrReceiver) {
1165*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref;
1166*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, AddRef()).Times(1);
1167*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, Release()).Times(1);
1168*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1169*6777b538SAndroid Build Coastguard Worker
1170*6777b538SAndroid Build Coastguard Worker HasRef* ptr = &has_ref;
1171*6777b538SAndroid Build Coastguard Worker auto ptr_cb = TypeParam::Bind(&HasRef::HasAtLeastOneRef, ptr);
1172*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, std::move(ptr_cb).Run());
1173*6777b538SAndroid Build Coastguard Worker }
1174*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindVariantsTest,RawPtrReceiver)1175*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, RawPtrReceiver) {
1176*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref;
1177*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, AddRef()).Times(1);
1178*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, Release()).Times(1);
1179*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1180*6777b538SAndroid Build Coastguard Worker
1181*6777b538SAndroid Build Coastguard Worker raw_ptr<HasRef> rawptr(&has_ref);
1182*6777b538SAndroid Build Coastguard Worker auto rawptr_cb = TypeParam::Bind(&HasRef::HasAtLeastOneRef, rawptr);
1183*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, std::move(rawptr_cb).Run());
1184*6777b538SAndroid Build Coastguard Worker }
1185*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindVariantsTest,UnretainedRawRefReceiver)1186*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindVariantsTest, UnretainedRawRefReceiver) {
1187*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref;
1188*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, AddRef()).Times(0);
1189*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, Release()).Times(0);
1190*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillRepeatedly(Return(true));
1191*6777b538SAndroid Build Coastguard Worker
1192*6777b538SAndroid Build Coastguard Worker raw_ref<HasRef> raw_has_ref(has_ref);
1193*6777b538SAndroid Build Coastguard Worker auto has_ref_cb =
1194*6777b538SAndroid Build Coastguard Worker TypeParam::Bind(&HasRef::HasAtLeastOneRef, Unretained(raw_has_ref));
1195*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, std::move(has_ref_cb).Run());
1196*6777b538SAndroid Build Coastguard Worker
1197*6777b538SAndroid Build Coastguard Worker StrictMock<NoRef> no_ref;
1198*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, IntMethod0()).WillRepeatedly(Return(1));
1199*6777b538SAndroid Build Coastguard Worker
1200*6777b538SAndroid Build Coastguard Worker raw_ref<NoRef> raw_no_ref(has_ref);
1201*6777b538SAndroid Build Coastguard Worker auto no_ref_cb = TypeParam::Bind(&NoRef::IntMethod0, Unretained(raw_no_ref));
1202*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, std::move(no_ref_cb).Run());
1203*6777b538SAndroid Build Coastguard Worker }
1204*6777b538SAndroid Build Coastguard Worker
1205*6777b538SAndroid Build Coastguard Worker // Tests for Passed() wrapper support:
1206*6777b538SAndroid Build Coastguard Worker // - Passed() can be constructed from a pointer to scoper.
1207*6777b538SAndroid Build Coastguard Worker // - Passed() can be constructed from a scoper rvalue.
1208*6777b538SAndroid Build Coastguard Worker // - Using Passed() gives Callback Ownership.
1209*6777b538SAndroid Build Coastguard Worker // - Ownership is transferred from Callback to callee on the first Run().
1210*6777b538SAndroid Build Coastguard Worker // - Callback supports unbound arguments.
1211*6777b538SAndroid Build Coastguard Worker template <typename T>
1212*6777b538SAndroid Build Coastguard Worker class BindMoveOnlyTypeTest : public ::testing::Test {};
1213*6777b538SAndroid Build Coastguard Worker
1214*6777b538SAndroid Build Coastguard Worker struct CustomDeleter {
operator ()base::__anon8a4af9fd0111::CustomDeleter1215*6777b538SAndroid Build Coastguard Worker void operator()(DeleteCounter* c) { delete c; }
1216*6777b538SAndroid Build Coastguard Worker };
1217*6777b538SAndroid Build Coastguard Worker
1218*6777b538SAndroid Build Coastguard Worker using MoveOnlyTypesToTest =
1219*6777b538SAndroid Build Coastguard Worker ::testing::Types<std::unique_ptr<DeleteCounter>,
1220*6777b538SAndroid Build Coastguard Worker std::unique_ptr<DeleteCounter, CustomDeleter>>;
1221*6777b538SAndroid Build Coastguard Worker TYPED_TEST_SUITE(BindMoveOnlyTypeTest, MoveOnlyTypesToTest);
1222*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindMoveOnlyTypeTest,PassedToBoundCallback)1223*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindMoveOnlyTypeTest, PassedToBoundCallback) {
1224*6777b538SAndroid Build Coastguard Worker int deletes = 0;
1225*6777b538SAndroid Build Coastguard Worker
1226*6777b538SAndroid Build Coastguard Worker TypeParam ptr(new DeleteCounter(&deletes));
1227*6777b538SAndroid Build Coastguard Worker RepeatingCallback<TypeParam()> callback =
1228*6777b538SAndroid Build Coastguard Worker BindRepeating(&PassThru<TypeParam>, Passed(&ptr));
1229*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(ptr.get());
1230*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
1231*6777b538SAndroid Build Coastguard Worker
1232*6777b538SAndroid Build Coastguard Worker // If we never invoke the Callback, it retains ownership and deletes.
1233*6777b538SAndroid Build Coastguard Worker callback.Reset();
1234*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
1235*6777b538SAndroid Build Coastguard Worker }
1236*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindMoveOnlyTypeTest,PassedWithRvalue)1237*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindMoveOnlyTypeTest, PassedWithRvalue) {
1238*6777b538SAndroid Build Coastguard Worker int deletes = 0;
1239*6777b538SAndroid Build Coastguard Worker RepeatingCallback<TypeParam()> callback = BindRepeating(
1240*6777b538SAndroid Build Coastguard Worker &PassThru<TypeParam>, Passed(TypeParam(new DeleteCounter(&deletes))));
1241*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
1242*6777b538SAndroid Build Coastguard Worker
1243*6777b538SAndroid Build Coastguard Worker // If we never invoke the Callback, it retains ownership and deletes.
1244*6777b538SAndroid Build Coastguard Worker callback.Reset();
1245*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
1246*6777b538SAndroid Build Coastguard Worker }
1247*6777b538SAndroid Build Coastguard Worker
1248*6777b538SAndroid Build Coastguard Worker // Check that ownership can be transferred back out.
TYPED_TEST(BindMoveOnlyTypeTest,ReturnMoveOnlyType)1249*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindMoveOnlyTypeTest, ReturnMoveOnlyType) {
1250*6777b538SAndroid Build Coastguard Worker int deletes = 0;
1251*6777b538SAndroid Build Coastguard Worker DeleteCounter* counter = new DeleteCounter(&deletes);
1252*6777b538SAndroid Build Coastguard Worker RepeatingCallback<TypeParam()> callback =
1253*6777b538SAndroid Build Coastguard Worker BindRepeating(&PassThru<TypeParam>, Passed(TypeParam(counter)));
1254*6777b538SAndroid Build Coastguard Worker TypeParam result = callback.Run();
1255*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(counter, result.get());
1256*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
1257*6777b538SAndroid Build Coastguard Worker
1258*6777b538SAndroid Build Coastguard Worker // Resetting does not delete since ownership was transferred.
1259*6777b538SAndroid Build Coastguard Worker callback.Reset();
1260*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, deletes);
1261*6777b538SAndroid Build Coastguard Worker
1262*6777b538SAndroid Build Coastguard Worker // Ensure that we actually did get ownership.
1263*6777b538SAndroid Build Coastguard Worker result.reset();
1264*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
1265*6777b538SAndroid Build Coastguard Worker }
1266*6777b538SAndroid Build Coastguard Worker
TYPED_TEST(BindMoveOnlyTypeTest,UnboundForwarding)1267*6777b538SAndroid Build Coastguard Worker TYPED_TEST(BindMoveOnlyTypeTest, UnboundForwarding) {
1268*6777b538SAndroid Build Coastguard Worker int deletes = 0;
1269*6777b538SAndroid Build Coastguard Worker TypeParam ptr(new DeleteCounter(&deletes));
1270*6777b538SAndroid Build Coastguard Worker // Test unbound argument forwarding.
1271*6777b538SAndroid Build Coastguard Worker RepeatingCallback<TypeParam(TypeParam)> cb_unbound =
1272*6777b538SAndroid Build Coastguard Worker BindRepeating(&PassThru<TypeParam>);
1273*6777b538SAndroid Build Coastguard Worker cb_unbound.Run(std::move(ptr));
1274*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, deletes);
1275*6777b538SAndroid Build Coastguard Worker }
1276*6777b538SAndroid Build Coastguard Worker
VerifyVector(const std::vector<std::unique_ptr<int>> & v)1277*6777b538SAndroid Build Coastguard Worker void VerifyVector(const std::vector<std::unique_ptr<int>>& v) {
1278*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(1u, v.size());
1279*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(12345, *v[0]);
1280*6777b538SAndroid Build Coastguard Worker }
1281*6777b538SAndroid Build Coastguard Worker
AcceptAndReturnMoveOnlyVector(std::vector<std::unique_ptr<int>> v)1282*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<int>> AcceptAndReturnMoveOnlyVector(
1283*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<int>> v) {
1284*6777b538SAndroid Build Coastguard Worker VerifyVector(v);
1285*6777b538SAndroid Build Coastguard Worker return v;
1286*6777b538SAndroid Build Coastguard Worker }
1287*6777b538SAndroid Build Coastguard Worker
1288*6777b538SAndroid Build Coastguard Worker // Test that a vector containing move-only types can be used with Callback.
TEST_F(BindTest,BindMoveOnlyVector)1289*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, BindMoveOnlyVector) {
1290*6777b538SAndroid Build Coastguard Worker using MoveOnlyVector = std::vector<std::unique_ptr<int>>;
1291*6777b538SAndroid Build Coastguard Worker
1292*6777b538SAndroid Build Coastguard Worker MoveOnlyVector v;
1293*6777b538SAndroid Build Coastguard Worker v.push_back(std::make_unique<int>(12345));
1294*6777b538SAndroid Build Coastguard Worker
1295*6777b538SAndroid Build Coastguard Worker // Early binding should work:
1296*6777b538SAndroid Build Coastguard Worker RepeatingCallback<MoveOnlyVector()> bound_cb =
1297*6777b538SAndroid Build Coastguard Worker BindRepeating(&AcceptAndReturnMoveOnlyVector, Passed(&v));
1298*6777b538SAndroid Build Coastguard Worker MoveOnlyVector intermediate_result = bound_cb.Run();
1299*6777b538SAndroid Build Coastguard Worker VerifyVector(intermediate_result);
1300*6777b538SAndroid Build Coastguard Worker
1301*6777b538SAndroid Build Coastguard Worker // As should passing it as an argument to Run():
1302*6777b538SAndroid Build Coastguard Worker RepeatingCallback<MoveOnlyVector(MoveOnlyVector)> unbound_cb =
1303*6777b538SAndroid Build Coastguard Worker BindRepeating(&AcceptAndReturnMoveOnlyVector);
1304*6777b538SAndroid Build Coastguard Worker MoveOnlyVector final_result = unbound_cb.Run(std::move(intermediate_result));
1305*6777b538SAndroid Build Coastguard Worker VerifyVector(final_result);
1306*6777b538SAndroid Build Coastguard Worker }
1307*6777b538SAndroid Build Coastguard Worker
1308*6777b538SAndroid Build Coastguard Worker // Using Passed() on a functor should not cause a compile error.
TEST_F(BindTest,PassedFunctor)1309*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, PassedFunctor) {
1310*6777b538SAndroid Build Coastguard Worker struct S {
1311*6777b538SAndroid Build Coastguard Worker void operator()() const {}
1312*6777b538SAndroid Build Coastguard Worker };
1313*6777b538SAndroid Build Coastguard Worker
1314*6777b538SAndroid Build Coastguard Worker BindRepeating(Passed(S())).Run();
1315*6777b538SAndroid Build Coastguard Worker }
1316*6777b538SAndroid Build Coastguard Worker
1317*6777b538SAndroid Build Coastguard Worker // Argument copy-constructor usage for non-reference copy-only parameters.
1318*6777b538SAndroid Build Coastguard Worker // - Bound arguments are only copied once.
1319*6777b538SAndroid Build Coastguard Worker // - Forwarded arguments are only copied once.
1320*6777b538SAndroid Build Coastguard Worker // - Forwarded arguments with coercions are only copied twice (once for the
1321*6777b538SAndroid Build Coastguard Worker // coercion, and one for the final dispatch).
TEST_F(BindTest,ArgumentCopies)1322*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ArgumentCopies) {
1323*6777b538SAndroid Build Coastguard Worker int copies = 0;
1324*6777b538SAndroid Build Coastguard Worker int assigns = 0;
1325*6777b538SAndroid Build Coastguard Worker
1326*6777b538SAndroid Build Coastguard Worker CopyCounter counter(&copies, &assigns);
1327*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyCounter>::Run, counter);
1328*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, copies);
1329*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1330*6777b538SAndroid Build Coastguard Worker
1331*6777b538SAndroid Build Coastguard Worker copies = 0;
1332*6777b538SAndroid Build Coastguard Worker assigns = 0;
1333*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyCounter>::Run,
1334*6777b538SAndroid Build Coastguard Worker CopyCounter(&copies, &assigns));
1335*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, copies);
1336*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1337*6777b538SAndroid Build Coastguard Worker
1338*6777b538SAndroid Build Coastguard Worker copies = 0;
1339*6777b538SAndroid Build Coastguard Worker assigns = 0;
1340*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyCounter>::Run).Run(counter);
1341*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, copies);
1342*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1343*6777b538SAndroid Build Coastguard Worker
1344*6777b538SAndroid Build Coastguard Worker copies = 0;
1345*6777b538SAndroid Build Coastguard Worker assigns = 0;
1346*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyCounter>::Run)
1347*6777b538SAndroid Build Coastguard Worker .Run(CopyCounter(&copies, &assigns));
1348*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, copies);
1349*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1350*6777b538SAndroid Build Coastguard Worker
1351*6777b538SAndroid Build Coastguard Worker copies = 0;
1352*6777b538SAndroid Build Coastguard Worker assigns = 0;
1353*6777b538SAndroid Build Coastguard Worker DerivedCopyMoveCounter derived(&copies, &assigns, nullptr, nullptr);
1354*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyCounter>::Run).Run(CopyCounter(derived));
1355*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, copies);
1356*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1357*6777b538SAndroid Build Coastguard Worker
1358*6777b538SAndroid Build Coastguard Worker copies = 0;
1359*6777b538SAndroid Build Coastguard Worker assigns = 0;
1360*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyCounter>::Run)
1361*6777b538SAndroid Build Coastguard Worker .Run(CopyCounter(
1362*6777b538SAndroid Build Coastguard Worker DerivedCopyMoveCounter(&copies, &assigns, nullptr, nullptr)));
1363*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, copies);
1364*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1365*6777b538SAndroid Build Coastguard Worker }
1366*6777b538SAndroid Build Coastguard Worker
1367*6777b538SAndroid Build Coastguard Worker // Argument move-constructor usage for move-only parameters.
1368*6777b538SAndroid Build Coastguard Worker // - Bound arguments passed by move are not copied.
TEST_F(BindTest,ArgumentMoves)1369*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ArgumentMoves) {
1370*6777b538SAndroid Build Coastguard Worker int move_constructs = 0;
1371*6777b538SAndroid Build Coastguard Worker int move_assigns = 0;
1372*6777b538SAndroid Build Coastguard Worker
1373*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<const MoveCounter&>::Run,
1374*6777b538SAndroid Build Coastguard Worker MoveCounter(&move_constructs, &move_assigns));
1375*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, move_constructs);
1376*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1377*6777b538SAndroid Build Coastguard Worker
1378*6777b538SAndroid Build Coastguard Worker // TODO(tzik): Support binding move-only type into a non-reference parameter
1379*6777b538SAndroid Build Coastguard Worker // of a variant of Callback.
1380*6777b538SAndroid Build Coastguard Worker
1381*6777b538SAndroid Build Coastguard Worker move_constructs = 0;
1382*6777b538SAndroid Build Coastguard Worker move_assigns = 0;
1383*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<MoveCounter>::Run)
1384*6777b538SAndroid Build Coastguard Worker .Run(MoveCounter(&move_constructs, &move_assigns));
1385*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, move_constructs);
1386*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1387*6777b538SAndroid Build Coastguard Worker
1388*6777b538SAndroid Build Coastguard Worker move_constructs = 0;
1389*6777b538SAndroid Build Coastguard Worker move_assigns = 0;
1390*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<MoveCounter>::Run)
1391*6777b538SAndroid Build Coastguard Worker .Run(MoveCounter(DerivedCopyMoveCounter(
1392*6777b538SAndroid Build Coastguard Worker nullptr, nullptr, &move_constructs, &move_assigns)));
1393*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, move_constructs);
1394*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1395*6777b538SAndroid Build Coastguard Worker }
1396*6777b538SAndroid Build Coastguard Worker
1397*6777b538SAndroid Build Coastguard Worker // Argument constructor usage for non-reference movable-copyable
1398*6777b538SAndroid Build Coastguard Worker // parameters.
1399*6777b538SAndroid Build Coastguard Worker // - Bound arguments passed by move are not copied.
1400*6777b538SAndroid Build Coastguard Worker // - Forwarded arguments are only copied once.
1401*6777b538SAndroid Build Coastguard Worker // - Forwarded arguments with coercions are only copied once and moved once.
TEST_F(BindTest,ArgumentCopiesAndMoves)1402*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ArgumentCopiesAndMoves) {
1403*6777b538SAndroid Build Coastguard Worker int copies = 0;
1404*6777b538SAndroid Build Coastguard Worker int assigns = 0;
1405*6777b538SAndroid Build Coastguard Worker int move_constructs = 0;
1406*6777b538SAndroid Build Coastguard Worker int move_assigns = 0;
1407*6777b538SAndroid Build Coastguard Worker
1408*6777b538SAndroid Build Coastguard Worker CopyMoveCounter counter(&copies, &assigns, &move_constructs, &move_assigns);
1409*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run, counter);
1410*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, copies);
1411*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1412*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_constructs);
1413*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1414*6777b538SAndroid Build Coastguard Worker
1415*6777b538SAndroid Build Coastguard Worker copies = 0;
1416*6777b538SAndroid Build Coastguard Worker assigns = 0;
1417*6777b538SAndroid Build Coastguard Worker move_constructs = 0;
1418*6777b538SAndroid Build Coastguard Worker move_assigns = 0;
1419*6777b538SAndroid Build Coastguard Worker BindRepeating(
1420*6777b538SAndroid Build Coastguard Worker &VoidPolymorphic<CopyMoveCounter>::Run,
1421*6777b538SAndroid Build Coastguard Worker CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1422*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, copies);
1423*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1424*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, move_constructs);
1425*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1426*6777b538SAndroid Build Coastguard Worker
1427*6777b538SAndroid Build Coastguard Worker copies = 0;
1428*6777b538SAndroid Build Coastguard Worker assigns = 0;
1429*6777b538SAndroid Build Coastguard Worker move_constructs = 0;
1430*6777b538SAndroid Build Coastguard Worker move_assigns = 0;
1431*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run).Run(counter);
1432*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, copies);
1433*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1434*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, move_constructs);
1435*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1436*6777b538SAndroid Build Coastguard Worker
1437*6777b538SAndroid Build Coastguard Worker copies = 0;
1438*6777b538SAndroid Build Coastguard Worker assigns = 0;
1439*6777b538SAndroid Build Coastguard Worker move_constructs = 0;
1440*6777b538SAndroid Build Coastguard Worker move_assigns = 0;
1441*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
1442*6777b538SAndroid Build Coastguard Worker .Run(CopyMoveCounter(&copies, &assigns, &move_constructs, &move_assigns));
1443*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, copies);
1444*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1445*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, move_constructs);
1446*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1447*6777b538SAndroid Build Coastguard Worker
1448*6777b538SAndroid Build Coastguard Worker DerivedCopyMoveCounter derived_counter(&copies, &assigns, &move_constructs,
1449*6777b538SAndroid Build Coastguard Worker &move_assigns);
1450*6777b538SAndroid Build Coastguard Worker copies = 0;
1451*6777b538SAndroid Build Coastguard Worker assigns = 0;
1452*6777b538SAndroid Build Coastguard Worker move_constructs = 0;
1453*6777b538SAndroid Build Coastguard Worker move_assigns = 0;
1454*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
1455*6777b538SAndroid Build Coastguard Worker .Run(CopyMoveCounter(derived_counter));
1456*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, copies);
1457*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1458*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, move_constructs);
1459*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1460*6777b538SAndroid Build Coastguard Worker
1461*6777b538SAndroid Build Coastguard Worker copies = 0;
1462*6777b538SAndroid Build Coastguard Worker assigns = 0;
1463*6777b538SAndroid Build Coastguard Worker move_constructs = 0;
1464*6777b538SAndroid Build Coastguard Worker move_assigns = 0;
1465*6777b538SAndroid Build Coastguard Worker BindRepeating(&VoidPolymorphic<CopyMoveCounter>::Run)
1466*6777b538SAndroid Build Coastguard Worker .Run(CopyMoveCounter(DerivedCopyMoveCounter(
1467*6777b538SAndroid Build Coastguard Worker &copies, &assigns, &move_constructs, &move_assigns)));
1468*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, copies);
1469*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, assigns);
1470*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, move_constructs);
1471*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, move_assigns);
1472*6777b538SAndroid Build Coastguard Worker }
1473*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,RepeatingWithoutPassed)1474*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, RepeatingWithoutPassed) {
1475*6777b538SAndroid Build Coastguard Worker // It should be possible to use a move-only type with `BindRepeating` without
1476*6777b538SAndroid Build Coastguard Worker // `Passed` if running the callback does not require copying the instance.
1477*6777b538SAndroid Build Coastguard Worker struct S {
1478*6777b538SAndroid Build Coastguard Worker S() = default;
1479*6777b538SAndroid Build Coastguard Worker S(S&&) = default;
1480*6777b538SAndroid Build Coastguard Worker S& operator=(S&&) = default;
1481*6777b538SAndroid Build Coastguard Worker } s;
1482*6777b538SAndroid Build Coastguard Worker BindRepeating([](const S&) {}, std::move(s));
1483*6777b538SAndroid Build Coastguard Worker }
1484*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,CapturelessLambda)1485*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, CapturelessLambda) {
1486*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindRepeating([] { return 42; }).Run());
1487*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindRepeating([](int i) { return i * 7; }, 6).Run());
1488*6777b538SAndroid Build Coastguard Worker
1489*6777b538SAndroid Build Coastguard Worker int x = 1;
1490*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void(int)> cb =
1491*6777b538SAndroid Build Coastguard Worker BindRepeating([](int* x, int i) { *x *= i; }, Unretained(&x));
1492*6777b538SAndroid Build Coastguard Worker cb.Run(6);
1493*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(6, x);
1494*6777b538SAndroid Build Coastguard Worker cb.Run(7);
1495*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, x);
1496*6777b538SAndroid Build Coastguard Worker }
1497*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,EmptyFunctor)1498*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, EmptyFunctor) {
1499*6777b538SAndroid Build Coastguard Worker struct NonEmptyFunctor {
1500*6777b538SAndroid Build Coastguard Worker int operator()() const { return x; }
1501*6777b538SAndroid Build Coastguard Worker int x = 42;
1502*6777b538SAndroid Build Coastguard Worker };
1503*6777b538SAndroid Build Coastguard Worker
1504*6777b538SAndroid Build Coastguard Worker struct EmptyFunctor {
1505*6777b538SAndroid Build Coastguard Worker int operator()() { return 42; }
1506*6777b538SAndroid Build Coastguard Worker };
1507*6777b538SAndroid Build Coastguard Worker
1508*6777b538SAndroid Build Coastguard Worker struct EmptyFunctorConst {
1509*6777b538SAndroid Build Coastguard Worker int operator()() const { return 42; }
1510*6777b538SAndroid Build Coastguard Worker };
1511*6777b538SAndroid Build Coastguard Worker
1512*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindLambdaForTesting(NonEmptyFunctor()).Run());
1513*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(EmptyFunctor()).Run());
1514*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(EmptyFunctorConst()).Run());
1515*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindRepeating(EmptyFunctorConst()).Run());
1516*6777b538SAndroid Build Coastguard Worker }
1517*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,CapturingLambdaForTesting)1518*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, CapturingLambdaForTesting) {
1519*6777b538SAndroid Build Coastguard Worker // Test copyable lambdas.
1520*6777b538SAndroid Build Coastguard Worker int x = 6;
1521*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindLambdaForTesting([=](int y) { return x * y; }).Run(7));
1522*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42,
1523*6777b538SAndroid Build Coastguard Worker BindLambdaForTesting([=](int y) mutable { return x *= y; }).Run(7));
1524*6777b538SAndroid Build Coastguard Worker auto f = [x](std::unique_ptr<int> y) { return x * *y; };
1525*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindLambdaForTesting(f).Run(std::make_unique<int>(7)));
1526*6777b538SAndroid Build Coastguard Worker
1527*6777b538SAndroid Build Coastguard Worker // Test move-only lambdas.
1528*6777b538SAndroid Build Coastguard Worker auto y = std::make_unique<int>(7);
1529*6777b538SAndroid Build Coastguard Worker auto g = [y = std::move(y)](int& x) mutable {
1530*6777b538SAndroid Build Coastguard Worker return x * *std::exchange(y, nullptr);
1531*6777b538SAndroid Build Coastguard Worker };
1532*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindLambdaForTesting(std::move(g)).Run(x));
1533*6777b538SAndroid Build Coastguard Worker
1534*6777b538SAndroid Build Coastguard Worker y = std::make_unique<int>(7);
1535*6777b538SAndroid Build Coastguard Worker auto h = [x, y = std::move(y)] { return x * *y; };
1536*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindLambdaForTesting(std::move(h)).Run());
1537*6777b538SAndroid Build Coastguard Worker }
1538*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,Cancellation)1539*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, Cancellation) {
1540*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(no_ref_, VoidMethodWithIntArg(_)).Times(2);
1541*6777b538SAndroid Build Coastguard Worker
1542*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<NoRef> weak_factory(&no_ref_);
1543*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void(int)> cb =
1544*6777b538SAndroid Build Coastguard Worker BindRepeating(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1545*6777b538SAndroid Build Coastguard Worker RepeatingClosure cb2 = BindRepeating(cb, 8);
1546*6777b538SAndroid Build Coastguard Worker OnceClosure cb3 = BindOnce(cb, 8);
1547*6777b538SAndroid Build Coastguard Worker
1548*6777b538SAndroid Build Coastguard Worker OnceCallback<void(int)> cb4 =
1549*6777b538SAndroid Build Coastguard Worker BindOnce(&NoRef::VoidMethodWithIntArg, weak_factory.GetWeakPtr());
1550*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cb4.IsCancelled());
1551*6777b538SAndroid Build Coastguard Worker
1552*6777b538SAndroid Build Coastguard Worker OnceClosure cb5 = BindOnce(std::move(cb4), 8);
1553*6777b538SAndroid Build Coastguard Worker
1554*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cb.IsCancelled());
1555*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cb2.IsCancelled());
1556*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cb3.IsCancelled());
1557*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(cb5.IsCancelled());
1558*6777b538SAndroid Build Coastguard Worker
1559*6777b538SAndroid Build Coastguard Worker cb.Run(6);
1560*6777b538SAndroid Build Coastguard Worker cb2.Run();
1561*6777b538SAndroid Build Coastguard Worker
1562*6777b538SAndroid Build Coastguard Worker weak_factory.InvalidateWeakPtrs();
1563*6777b538SAndroid Build Coastguard Worker
1564*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(cb.IsCancelled());
1565*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(cb2.IsCancelled());
1566*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(cb3.IsCancelled());
1567*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(cb5.IsCancelled());
1568*6777b538SAndroid Build Coastguard Worker
1569*6777b538SAndroid Build Coastguard Worker cb.Run(6);
1570*6777b538SAndroid Build Coastguard Worker cb2.Run();
1571*6777b538SAndroid Build Coastguard Worker std::move(cb3).Run();
1572*6777b538SAndroid Build Coastguard Worker std::move(cb5).Run();
1573*6777b538SAndroid Build Coastguard Worker }
1574*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OnceCallback)1575*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OnceCallback) {
1576*6777b538SAndroid Build Coastguard Worker // Check if Callback variants have declarations of conversions as expected.
1577*6777b538SAndroid Build Coastguard Worker // Copy constructor and assignment of RepeatingCallback.
1578*6777b538SAndroid Build Coastguard Worker static_assert(
1579*6777b538SAndroid Build Coastguard Worker std::is_constructible_v<RepeatingClosure, const RepeatingClosure&>,
1580*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be copyable.");
1581*6777b538SAndroid Build Coastguard Worker static_assert(std::is_assignable_v<RepeatingClosure, const RepeatingClosure&>,
1582*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be copy-assignable.");
1583*6777b538SAndroid Build Coastguard Worker
1584*6777b538SAndroid Build Coastguard Worker // Move constructor and assignment of RepeatingCallback.
1585*6777b538SAndroid Build Coastguard Worker static_assert(std::is_constructible_v<RepeatingClosure, RepeatingClosure&&>,
1586*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be movable.");
1587*6777b538SAndroid Build Coastguard Worker static_assert(std::is_assignable_v<RepeatingClosure, RepeatingClosure&&>,
1588*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be move-assignable");
1589*6777b538SAndroid Build Coastguard Worker
1590*6777b538SAndroid Build Coastguard Worker // Conversions from OnceCallback to RepeatingCallback.
1591*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_constructible_v<RepeatingClosure, const OnceClosure&>,
1592*6777b538SAndroid Build Coastguard Worker "OnceClosure should not be convertible to RepeatingClosure.");
1593*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_assignable_v<RepeatingClosure, const OnceClosure&>,
1594*6777b538SAndroid Build Coastguard Worker "OnceClosure should not be convertible to RepeatingClosure.");
1595*6777b538SAndroid Build Coastguard Worker
1596*6777b538SAndroid Build Coastguard Worker // Destructive conversions from OnceCallback to RepeatingCallback.
1597*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_constructible_v<RepeatingClosure, OnceClosure&&>,
1598*6777b538SAndroid Build Coastguard Worker "OnceClosure should not be convertible to RepeatingClosure.");
1599*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_assignable_v<RepeatingClosure, OnceClosure&&>,
1600*6777b538SAndroid Build Coastguard Worker "OnceClosure should not be convertible to RepeatingClosure.");
1601*6777b538SAndroid Build Coastguard Worker
1602*6777b538SAndroid Build Coastguard Worker // Copy constructor and assignment of OnceCallback.
1603*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_constructible_v<OnceClosure, const OnceClosure&>,
1604*6777b538SAndroid Build Coastguard Worker "OnceClosure should not be copyable.");
1605*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_assignable_v<OnceClosure, const OnceClosure&>,
1606*6777b538SAndroid Build Coastguard Worker "OnceClosure should not be copy-assignable");
1607*6777b538SAndroid Build Coastguard Worker
1608*6777b538SAndroid Build Coastguard Worker // Move constructor and assignment of OnceCallback.
1609*6777b538SAndroid Build Coastguard Worker static_assert(std::is_constructible_v<OnceClosure, OnceClosure&&>,
1610*6777b538SAndroid Build Coastguard Worker "OnceClosure should be movable.");
1611*6777b538SAndroid Build Coastguard Worker static_assert(std::is_assignable_v<OnceClosure, OnceClosure&&>,
1612*6777b538SAndroid Build Coastguard Worker "OnceClosure should be move-assignable.");
1613*6777b538SAndroid Build Coastguard Worker
1614*6777b538SAndroid Build Coastguard Worker // Conversions from RepeatingCallback to OnceCallback.
1615*6777b538SAndroid Build Coastguard Worker static_assert(std::is_constructible_v<OnceClosure, const RepeatingClosure&>,
1616*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be convertible to OnceClosure.");
1617*6777b538SAndroid Build Coastguard Worker static_assert(std::is_assignable_v<OnceClosure, const RepeatingClosure&>,
1618*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be convertible to OnceClosure.");
1619*6777b538SAndroid Build Coastguard Worker
1620*6777b538SAndroid Build Coastguard Worker // Destructive conversions from RepeatingCallback to OnceCallback.
1621*6777b538SAndroid Build Coastguard Worker static_assert(std::is_constructible_v<OnceClosure, RepeatingClosure&&>,
1622*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be convertible to OnceClosure.");
1623*6777b538SAndroid Build Coastguard Worker static_assert(std::is_assignable_v<OnceClosure, RepeatingClosure&&>,
1624*6777b538SAndroid Build Coastguard Worker "RepeatingClosure should be covretible to OnceClosure.");
1625*6777b538SAndroid Build Coastguard Worker
1626*6777b538SAndroid Build Coastguard Worker OnceClosure cb = BindOnce(&VoidPolymorphic<>::Run);
1627*6777b538SAndroid Build Coastguard Worker std::move(cb).Run();
1628*6777b538SAndroid Build Coastguard Worker
1629*6777b538SAndroid Build Coastguard Worker // RepeatingCallback should be convertible to OnceCallback.
1630*6777b538SAndroid Build Coastguard Worker OnceClosure cb2 = BindRepeating(&VoidPolymorphic<>::Run);
1631*6777b538SAndroid Build Coastguard Worker std::move(cb2).Run();
1632*6777b538SAndroid Build Coastguard Worker
1633*6777b538SAndroid Build Coastguard Worker RepeatingClosure cb3 = BindRepeating(&VoidPolymorphic<>::Run);
1634*6777b538SAndroid Build Coastguard Worker cb = cb3;
1635*6777b538SAndroid Build Coastguard Worker std::move(cb).Run();
1636*6777b538SAndroid Build Coastguard Worker
1637*6777b538SAndroid Build Coastguard Worker cb = std::move(cb2);
1638*6777b538SAndroid Build Coastguard Worker
1639*6777b538SAndroid Build Coastguard Worker OnceCallback<void(int)> cb4 =
1640*6777b538SAndroid Build Coastguard Worker BindOnce(&VoidPolymorphic<std::unique_ptr<int>, int>::Run,
1641*6777b538SAndroid Build Coastguard Worker std::make_unique<int>(0));
1642*6777b538SAndroid Build Coastguard Worker BindOnce(std::move(cb4), 1).Run();
1643*6777b538SAndroid Build Coastguard Worker }
1644*6777b538SAndroid Build Coastguard Worker
1645*6777b538SAndroid Build Coastguard Worker // Callback construction and assignment tests.
1646*6777b538SAndroid Build Coastguard Worker // - Construction from an InvokerStorageHolder should not cause ref/deref.
1647*6777b538SAndroid Build Coastguard Worker // - Assignment from other callback should only cause one ref
1648*6777b538SAndroid Build Coastguard Worker //
1649*6777b538SAndroid Build Coastguard Worker // TODO(ajwong): Is there actually a way to test this?
1650*6777b538SAndroid Build Coastguard Worker
1651*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
FastCallFunc(int n)1652*6777b538SAndroid Build Coastguard Worker int __fastcall FastCallFunc(int n) {
1653*6777b538SAndroid Build Coastguard Worker return n;
1654*6777b538SAndroid Build Coastguard Worker }
1655*6777b538SAndroid Build Coastguard Worker
StdCallFunc(int n)1656*6777b538SAndroid Build Coastguard Worker int __stdcall StdCallFunc(int n) {
1657*6777b538SAndroid Build Coastguard Worker return n;
1658*6777b538SAndroid Build Coastguard Worker }
1659*6777b538SAndroid Build Coastguard Worker
1660*6777b538SAndroid Build Coastguard Worker // Windows specific calling convention support.
1661*6777b538SAndroid Build Coastguard Worker // - Can bind a __fastcall function.
1662*6777b538SAndroid Build Coastguard Worker // - Can bind a __stdcall function.
1663*6777b538SAndroid Build Coastguard Worker // - Can bind const and non-const __stdcall methods.
TEST_F(BindTest,WindowsCallingConventions)1664*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, WindowsCallingConventions) {
1665*6777b538SAndroid Build Coastguard Worker auto fastcall_cb = BindRepeating(&FastCallFunc, 1);
1666*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, fastcall_cb.Run());
1667*6777b538SAndroid Build Coastguard Worker
1668*6777b538SAndroid Build Coastguard Worker auto stdcall_cb = BindRepeating(&StdCallFunc, 2);
1669*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, stdcall_cb.Run());
1670*6777b538SAndroid Build Coastguard Worker
1671*6777b538SAndroid Build Coastguard Worker class MethodHolder {
1672*6777b538SAndroid Build Coastguard Worker public:
1673*6777b538SAndroid Build Coastguard Worker int __stdcall Func(int n) { return n; }
1674*6777b538SAndroid Build Coastguard Worker int __stdcall ConstFunc(int n) const { return -n; }
1675*6777b538SAndroid Build Coastguard Worker };
1676*6777b538SAndroid Build Coastguard Worker
1677*6777b538SAndroid Build Coastguard Worker MethodHolder obj;
1678*6777b538SAndroid Build Coastguard Worker auto stdcall_method_cb =
1679*6777b538SAndroid Build Coastguard Worker BindRepeating(&MethodHolder::Func, Unretained(&obj), 1);
1680*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, stdcall_method_cb.Run());
1681*6777b538SAndroid Build Coastguard Worker
1682*6777b538SAndroid Build Coastguard Worker const MethodHolder const_obj;
1683*6777b538SAndroid Build Coastguard Worker auto stdcall_const_method_cb =
1684*6777b538SAndroid Build Coastguard Worker BindRepeating(&MethodHolder::ConstFunc, Unretained(&const_obj), 1);
1685*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-1, stdcall_const_method_cb.Run());
1686*6777b538SAndroid Build Coastguard Worker }
1687*6777b538SAndroid Build Coastguard Worker #endif
1688*6777b538SAndroid Build Coastguard Worker
1689*6777b538SAndroid Build Coastguard Worker // Test unwrapping the various wrapping functions.
1690*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,UnwrapUnretained)1691*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, UnwrapUnretained) {
1692*6777b538SAndroid Build Coastguard Worker int i = 0;
1693*6777b538SAndroid Build Coastguard Worker auto unretained = Unretained(&i);
1694*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(&i, internal::Unwrap(unretained));
1695*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(&i, internal::Unwrap(std::move(unretained)));
1696*6777b538SAndroid Build Coastguard Worker }
1697*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,UnwrapRetainedRef)1698*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, UnwrapRetainedRef) {
1699*6777b538SAndroid Build Coastguard Worker auto p = MakeRefCounted<RefCountedData<int>>();
1700*6777b538SAndroid Build Coastguard Worker auto retained_ref = RetainedRef(p);
1701*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(p.get(), internal::Unwrap(retained_ref));
1702*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(p.get(), internal::Unwrap(std::move(retained_ref)));
1703*6777b538SAndroid Build Coastguard Worker }
1704*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,UnwrapOwned)1705*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, UnwrapOwned) {
1706*6777b538SAndroid Build Coastguard Worker {
1707*6777b538SAndroid Build Coastguard Worker int* p = new int;
1708*6777b538SAndroid Build Coastguard Worker auto owned = Owned(p);
1709*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(p, internal::Unwrap(owned));
1710*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(p, internal::Unwrap(std::move(owned)));
1711*6777b538SAndroid Build Coastguard Worker }
1712*6777b538SAndroid Build Coastguard Worker
1713*6777b538SAndroid Build Coastguard Worker {
1714*6777b538SAndroid Build Coastguard Worker auto p = std::make_unique<int>();
1715*6777b538SAndroid Build Coastguard Worker int* raw_p = p.get();
1716*6777b538SAndroid Build Coastguard Worker auto owned = Owned(std::move(p));
1717*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(raw_p, internal::Unwrap(owned));
1718*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(raw_p, internal::Unwrap(std::move(owned)));
1719*6777b538SAndroid Build Coastguard Worker }
1720*6777b538SAndroid Build Coastguard Worker }
1721*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,UnwrapPassed)1722*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, UnwrapPassed) {
1723*6777b538SAndroid Build Coastguard Worker int* p = new int;
1724*6777b538SAndroid Build Coastguard Worker auto passed = Passed(WrapUnique(p));
1725*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(p, internal::Unwrap(passed).get());
1726*6777b538SAndroid Build Coastguard Worker
1727*6777b538SAndroid Build Coastguard Worker p = new int;
1728*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(p, internal::Unwrap(Passed(WrapUnique(p))).get());
1729*6777b538SAndroid Build Coastguard Worker }
1730*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,BindNoexcept)1731*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, BindNoexcept) {
1732*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(&Noexcept).Run());
1733*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(&BindTest::NoexceptMethod, Unretained(this)).Run());
1734*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42,
1735*6777b538SAndroid Build Coastguard Worker BindOnce(&BindTest::ConstNoexceptMethod, Unretained(this)).Run());
1736*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(NoexceptFunctor()).Run());
1737*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(ConstNoexceptFunctor()).Run());
1738*6777b538SAndroid Build Coastguard Worker }
1739*6777b538SAndroid Build Coastguard Worker
PingPong(int * i_ptr)1740*6777b538SAndroid Build Coastguard Worker int PingPong(int* i_ptr) {
1741*6777b538SAndroid Build Coastguard Worker return *i_ptr;
1742*6777b538SAndroid Build Coastguard Worker }
1743*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,BindAndCallbacks)1744*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, BindAndCallbacks) {
1745*6777b538SAndroid Build Coastguard Worker int i = 123;
1746*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = &i;
1747*6777b538SAndroid Build Coastguard Worker
1748*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(PingPong, Unretained(p));
1749*6777b538SAndroid Build Coastguard Worker int res = std::move(callback).Run();
1750*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(123, res);
1751*6777b538SAndroid Build Coastguard Worker }
1752*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,ConvertibleArgs)1753*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, ConvertibleArgs) {
1754*6777b538SAndroid Build Coastguard Worker // Create two types S and T, such that you can convert a T to an S, but you
1755*6777b538SAndroid Build Coastguard Worker // cannot construct an S from a T.
1756*6777b538SAndroid Build Coastguard Worker struct T;
1757*6777b538SAndroid Build Coastguard Worker class S {
1758*6777b538SAndroid Build Coastguard Worker friend struct T;
1759*6777b538SAndroid Build Coastguard Worker explicit S(const T&) {}
1760*6777b538SAndroid Build Coastguard Worker };
1761*6777b538SAndroid Build Coastguard Worker struct T {
1762*6777b538SAndroid Build Coastguard Worker // NOLINTNEXTLINE(google-explicit-constructor)
1763*6777b538SAndroid Build Coastguard Worker operator S() const { return S(*this); }
1764*6777b538SAndroid Build Coastguard Worker };
1765*6777b538SAndroid Build Coastguard Worker static_assert(!std::is_constructible_v<S, T>);
1766*6777b538SAndroid Build Coastguard Worker static_assert(std::is_convertible_v<T, S>);
1767*6777b538SAndroid Build Coastguard Worker
1768*6777b538SAndroid Build Coastguard Worker // Ensure it's possible to pass a T to a function expecting an S.
1769*6777b538SAndroid Build Coastguard Worker void (*foo)(S) = +[](S) {};
1770*6777b538SAndroid Build Coastguard Worker const T t;
1771*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(foo, t);
1772*6777b538SAndroid Build Coastguard Worker std::move(callback).Run();
1773*6777b538SAndroid Build Coastguard Worker }
1774*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OverloadedOperator)1775*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OverloadedOperator) {
1776*6777b538SAndroid Build Coastguard Worker // Bind should be able to pick the correct `operator()()` to invoke on a
1777*6777b538SAndroid Build Coastguard Worker // functor from the supplied args.
1778*6777b538SAndroid Build Coastguard Worker struct S {
1779*6777b538SAndroid Build Coastguard Worker int operator()(int x) { return x; }
1780*6777b538SAndroid Build Coastguard Worker std::string operator()(std::string s) { return s; }
1781*6777b538SAndroid Build Coastguard Worker } s;
1782*6777b538SAndroid Build Coastguard Worker
1783*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(s, 42).Run());
1784*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Hello", BindOnce(s, "Hello").Run());
1785*6777b538SAndroid Build Coastguard Worker }
1786*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OverloadedOperatorQualifiers)1787*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OverloadedOperatorQualifiers) {
1788*6777b538SAndroid Build Coastguard Worker // Bind should be able to pick the correct `operator()()` to invoke on a
1789*6777b538SAndroid Build Coastguard Worker // functor when the only difference between the overloads is their qualifiers.
1790*6777b538SAndroid Build Coastguard Worker struct S {
1791*6777b538SAndroid Build Coastguard Worker int operator()() const& { return 1; }
1792*6777b538SAndroid Build Coastguard Worker int operator()() && { return 2; }
1793*6777b538SAndroid Build Coastguard Worker } s;
1794*6777b538SAndroid Build Coastguard Worker
1795*6777b538SAndroid Build Coastguard Worker // `BindRepeating()` normally stores a value and passes a const ref to the
1796*6777b538SAndroid Build Coastguard Worker // invoked method, regardless of whether lvalue or rvalue was originally
1797*6777b538SAndroid Build Coastguard Worker // provided.
1798*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, BindRepeating(s).Run());
1799*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, BindRepeating(S()).Run());
1800*6777b538SAndroid Build Coastguard Worker
1801*6777b538SAndroid Build Coastguard Worker // The exception is if `Passed()` is used, which tells `BindRepeating()` to
1802*6777b538SAndroid Build Coastguard Worker // move the specified argument during invocation.
1803*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, BindRepeating(Passed(S())).Run());
1804*6777b538SAndroid Build Coastguard Worker
1805*6777b538SAndroid Build Coastguard Worker // `BindOnce()` also stores a value, but it always moves that value during
1806*6777b538SAndroid Build Coastguard Worker // invocation, regardless of whether lvalue or rvalue was originally provided.
1807*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, BindOnce(s).Run());
1808*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, BindOnce(S()).Run());
1809*6777b538SAndroid Build Coastguard Worker }
1810*6777b538SAndroid Build Coastguard Worker
TEST_F(BindTest,OverloadedOperatorInexactMatch)1811*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, OverloadedOperatorInexactMatch) {
1812*6777b538SAndroid Build Coastguard Worker // The Bind machinery guesses signatures for overloaded `operator()()`s based
1813*6777b538SAndroid Build Coastguard Worker // on the decay_t<>s of the bound args. But as long as all args are bound and
1814*6777b538SAndroid Build Coastguard Worker // are convertible to exactly one overload's params, everything should work,
1815*6777b538SAndroid Build Coastguard Worker // even if the guess is slightly incorrect.
1816*6777b538SAndroid Build Coastguard Worker struct S {
1817*6777b538SAndroid Build Coastguard Worker int operator()(int x) { return x; }
1818*6777b538SAndroid Build Coastguard Worker // Machinery will guess that param type here is `std::string`.
1819*6777b538SAndroid Build Coastguard Worker std::string operator()(const std::string& s) { return s; }
1820*6777b538SAndroid Build Coastguard Worker } s;
1821*6777b538SAndroid Build Coastguard Worker
1822*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(42, BindOnce(s, 42).Run());
1823*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Hello", BindOnce(s, "Hello").Run());
1824*6777b538SAndroid Build Coastguard Worker }
1825*6777b538SAndroid Build Coastguard Worker
1826*6777b538SAndroid Build Coastguard Worker } // namespace
1827*6777b538SAndroid Build Coastguard Worker
1828*6777b538SAndroid Build Coastguard Worker // This simulates a race weak pointer that, unlike our `WeakPtr<>`,
1829*6777b538SAndroid Build Coastguard Worker // may become invalidated between `operator bool()` is tested and `Lock()`
1830*6777b538SAndroid Build Coastguard Worker // is called in the implementation of `Unwrap()`.
1831*6777b538SAndroid Build Coastguard Worker template <typename T>
1832*6777b538SAndroid Build Coastguard Worker struct MockRacyWeakPtr {
MockRacyWeakPtrbase::MockRacyWeakPtr1833*6777b538SAndroid Build Coastguard Worker explicit MockRacyWeakPtr(T*) {}
Lockbase::MockRacyWeakPtr1834*6777b538SAndroid Build Coastguard Worker T* Lock() const { return nullptr; }
1835*6777b538SAndroid Build Coastguard Worker
operator boolbase::MockRacyWeakPtr1836*6777b538SAndroid Build Coastguard Worker explicit operator bool() const { return true; }
1837*6777b538SAndroid Build Coastguard Worker };
1838*6777b538SAndroid Build Coastguard Worker
1839*6777b538SAndroid Build Coastguard Worker template <typename T>
1840*6777b538SAndroid Build Coastguard Worker struct IsWeakReceiver<MockRacyWeakPtr<T>> : std::true_type {};
1841*6777b538SAndroid Build Coastguard Worker
1842*6777b538SAndroid Build Coastguard Worker template <typename T>
1843*6777b538SAndroid Build Coastguard Worker struct BindUnwrapTraits<MockRacyWeakPtr<T>> {
Unwrapbase::BindUnwrapTraits1844*6777b538SAndroid Build Coastguard Worker static T* Unwrap(const MockRacyWeakPtr<T>& o) { return o.Lock(); }
1845*6777b538SAndroid Build Coastguard Worker };
1846*6777b538SAndroid Build Coastguard Worker
1847*6777b538SAndroid Build Coastguard Worker template <typename T>
1848*6777b538SAndroid Build Coastguard Worker struct MaybeValidTraits<MockRacyWeakPtr<T>> {
MaybeValidbase::MaybeValidTraits1849*6777b538SAndroid Build Coastguard Worker static bool MaybeValid(const MockRacyWeakPtr<T>& o) { return true; }
1850*6777b538SAndroid Build Coastguard Worker };
1851*6777b538SAndroid Build Coastguard Worker
1852*6777b538SAndroid Build Coastguard Worker namespace {
1853*6777b538SAndroid Build Coastguard Worker
1854*6777b538SAndroid Build Coastguard Worker // Note this only covers a case of racy weak pointer invalidation. Other
1855*6777b538SAndroid Build Coastguard Worker // weak pointer scenarios (such as a valid pointer) are covered
1856*6777b538SAndroid Build Coastguard Worker // in BindTest.WeakPtrFor{Once,Repeating}.
TEST_F(BindTest,BindRacyWeakPtrTest)1857*6777b538SAndroid Build Coastguard Worker TEST_F(BindTest, BindRacyWeakPtrTest) {
1858*6777b538SAndroid Build Coastguard Worker MockRacyWeakPtr<NoRef> weak(&no_ref_);
1859*6777b538SAndroid Build Coastguard Worker
1860*6777b538SAndroid Build Coastguard Worker RepeatingClosure cb = BindRepeating(&NoRef::VoidMethod0, weak);
1861*6777b538SAndroid Build Coastguard Worker cb.Run();
1862*6777b538SAndroid Build Coastguard Worker }
1863*6777b538SAndroid Build Coastguard Worker
1864*6777b538SAndroid Build Coastguard Worker // Test null callbacks cause a DCHECK.
TEST(BindDeathTest,NullCallback)1865*6777b538SAndroid Build Coastguard Worker TEST(BindDeathTest, NullCallback) {
1866*6777b538SAndroid Build Coastguard Worker RepeatingCallback<void(int)> null_cb;
1867*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(null_cb.is_null());
1868*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(BindRepeating(null_cb, 42));
1869*6777b538SAndroid Build Coastguard Worker }
1870*6777b538SAndroid Build Coastguard Worker
TEST(BindDeathTest,NullFunctionPointer)1871*6777b538SAndroid Build Coastguard Worker TEST(BindDeathTest, NullFunctionPointer) {
1872*6777b538SAndroid Build Coastguard Worker void (*null_function)(int) = nullptr;
1873*6777b538SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH(BindRepeating(null_function, 42));
1874*6777b538SAndroid Build Coastguard Worker }
1875*6777b538SAndroid Build Coastguard Worker
TEST(BindDeathTest,NullCallbackWithoutBoundArgs)1876*6777b538SAndroid Build Coastguard Worker TEST(BindDeathTest, NullCallbackWithoutBoundArgs) {
1877*6777b538SAndroid Build Coastguard Worker OnceCallback<void(int)> null_cb;
1878*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(null_cb.is_null());
1879*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(BindOnce(std::move(null_cb)));
1880*6777b538SAndroid Build Coastguard Worker }
1881*6777b538SAndroid Build Coastguard Worker
TEST(BindDeathTest,BanFirstOwnerOfRefCountedType)1882*6777b538SAndroid Build Coastguard Worker TEST(BindDeathTest, BanFirstOwnerOfRefCountedType) {
1883*6777b538SAndroid Build Coastguard Worker StrictMock<HasRef> has_ref;
1884*6777b538SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH({
1885*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillOnce(Return(false));
1886*6777b538SAndroid Build Coastguard Worker BindOnce(&HasRef::VoidMethod0, &has_ref);
1887*6777b538SAndroid Build Coastguard Worker });
1888*6777b538SAndroid Build Coastguard Worker
1889*6777b538SAndroid Build Coastguard Worker EXPECT_DCHECK_DEATH({
1890*6777b538SAndroid Build Coastguard Worker raw_ptr<HasRef> rawptr(&has_ref);
1891*6777b538SAndroid Build Coastguard Worker EXPECT_CALL(has_ref, HasAtLeastOneRef()).WillOnce(Return(false));
1892*6777b538SAndroid Build Coastguard Worker BindOnce(&HasRef::VoidMethod0, rawptr);
1893*6777b538SAndroid Build Coastguard Worker });
1894*6777b538SAndroid Build Coastguard Worker }
1895*6777b538SAndroid Build Coastguard Worker
1896*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
1897*6777b538SAndroid Build Coastguard Worker
HandleOOM(size_t unused_size)1898*6777b538SAndroid Build Coastguard Worker void HandleOOM(size_t unused_size) {
1899*6777b538SAndroid Build Coastguard Worker LOG(FATAL) << "Out of memory";
1900*6777b538SAndroid Build Coastguard Worker }
1901*6777b538SAndroid Build Coastguard Worker
1902*6777b538SAndroid Build Coastguard Worker // Basic set of options to mostly only enable `BackupRefPtr::kEnabled`.
1903*6777b538SAndroid Build Coastguard Worker // This avoids the boilerplate of having too much options enabled for simple
1904*6777b538SAndroid Build Coastguard Worker // testing purpose.
__anon8a4af9fd1102() 1905*6777b538SAndroid Build Coastguard Worker static constexpr auto kOnlyEnableBackupRefPtrOptions = []() {
1906*6777b538SAndroid Build Coastguard Worker partition_alloc::PartitionOptions opts;
1907*6777b538SAndroid Build Coastguard Worker opts.backup_ref_ptr = partition_alloc::PartitionOptions::kEnabled;
1908*6777b538SAndroid Build Coastguard Worker return opts;
1909*6777b538SAndroid Build Coastguard Worker }();
1910*6777b538SAndroid Build Coastguard Worker
1911*6777b538SAndroid Build Coastguard Worker class BindUnretainedDanglingInternalFixture : public BindTest {
1912*6777b538SAndroid Build Coastguard Worker public:
SetUp()1913*6777b538SAndroid Build Coastguard Worker void SetUp() override {
1914*6777b538SAndroid Build Coastguard Worker partition_alloc::PartitionAllocGlobalInit(HandleOOM);
1915*6777b538SAndroid Build Coastguard Worker enabled_feature_list_.InitWithFeaturesAndParameters(
1916*6777b538SAndroid Build Coastguard Worker {{features::kPartitionAllocUnretainedDanglingPtr, {{"mode", "crash"}}}},
1917*6777b538SAndroid Build Coastguard Worker {/* disabled_features */});
1918*6777b538SAndroid Build Coastguard Worker allocator::InstallUnretainedDanglingRawPtrChecks();
1919*6777b538SAndroid Build Coastguard Worker }
1920*6777b538SAndroid Build Coastguard Worker
TearDown()1921*6777b538SAndroid Build Coastguard Worker void TearDown() override {
1922*6777b538SAndroid Build Coastguard Worker enabled_feature_list_.Reset();
1923*6777b538SAndroid Build Coastguard Worker allocator::InstallUnretainedDanglingRawPtrChecks();
1924*6777b538SAndroid Build Coastguard Worker }
1925*6777b538SAndroid Build Coastguard Worker
1926*6777b538SAndroid Build Coastguard Worker // In unit tests, allocations being tested need to live in a separate PA
1927*6777b538SAndroid Build Coastguard Worker // root so the test code doesn't interfere with various counters. Following
1928*6777b538SAndroid Build Coastguard Worker // methods are helpers for managing allocations inside the separate allocator
1929*6777b538SAndroid Build Coastguard Worker // root.
1930*6777b538SAndroid Build Coastguard Worker template <typename T,
1931*6777b538SAndroid Build Coastguard Worker RawPtrTraits Traits = RawPtrTraits::kEmpty,
1932*6777b538SAndroid Build Coastguard Worker typename... Args>
Alloc(Args &&...args)1933*6777b538SAndroid Build Coastguard Worker raw_ptr<T, Traits> Alloc(Args&&... args) {
1934*6777b538SAndroid Build Coastguard Worker void* ptr = allocator_.root()->Alloc(sizeof(T), "");
1935*6777b538SAndroid Build Coastguard Worker T* p = new (reinterpret_cast<T*>(ptr)) T(std::forward<Args>(args)...);
1936*6777b538SAndroid Build Coastguard Worker return raw_ptr<T, Traits>(p);
1937*6777b538SAndroid Build Coastguard Worker }
1938*6777b538SAndroid Build Coastguard Worker template <typename T, RawPtrTraits Traits>
Free(raw_ptr<T,Traits> & ptr)1939*6777b538SAndroid Build Coastguard Worker void Free(raw_ptr<T, Traits>& ptr) {
1940*6777b538SAndroid Build Coastguard Worker allocator_.root()->Free(ptr.ExtractAsDangling());
1941*6777b538SAndroid Build Coastguard Worker }
1942*6777b538SAndroid Build Coastguard Worker
1943*6777b538SAndroid Build Coastguard Worker private:
1944*6777b538SAndroid Build Coastguard Worker test::ScopedFeatureList enabled_feature_list_;
1945*6777b538SAndroid Build Coastguard Worker partition_alloc::PartitionAllocatorForTesting allocator_{
1946*6777b538SAndroid Build Coastguard Worker kOnlyEnableBackupRefPtrOptions};
1947*6777b538SAndroid Build Coastguard Worker };
1948*6777b538SAndroid Build Coastguard Worker
1949*6777b538SAndroid Build Coastguard Worker class BindUnretainedDanglingTest
1950*6777b538SAndroid Build Coastguard Worker : public BindUnretainedDanglingInternalFixture {};
1951*6777b538SAndroid Build Coastguard Worker class BindUnretainedDanglingDeathTest
1952*6777b538SAndroid Build Coastguard Worker : public BindUnretainedDanglingInternalFixture {};
1953*6777b538SAndroid Build Coastguard Worker
PtrCheckFn(int * p)1954*6777b538SAndroid Build Coastguard Worker bool PtrCheckFn(int* p) {
1955*6777b538SAndroid Build Coastguard Worker return p != nullptr;
1956*6777b538SAndroid Build Coastguard Worker }
1957*6777b538SAndroid Build Coastguard Worker
RefCheckFn(const int & p)1958*6777b538SAndroid Build Coastguard Worker bool RefCheckFn(const int& p) {
1959*6777b538SAndroid Build Coastguard Worker return true;
1960*6777b538SAndroid Build Coastguard Worker }
1961*6777b538SAndroid Build Coastguard Worker
MayBeDanglingCheckFn(MayBeDangling<int> p)1962*6777b538SAndroid Build Coastguard Worker bool MayBeDanglingCheckFn(MayBeDangling<int> p) {
1963*6777b538SAndroid Build Coastguard Worker return p != nullptr;
1964*6777b538SAndroid Build Coastguard Worker }
1965*6777b538SAndroid Build Coastguard Worker
MayBeDanglingAndDummyTraitCheckFn(MayBeDangling<int,RawPtrTraits::kDummyForTest> p)1966*6777b538SAndroid Build Coastguard Worker bool MayBeDanglingAndDummyTraitCheckFn(
1967*6777b538SAndroid Build Coastguard Worker MayBeDangling<int, RawPtrTraits::kDummyForTest> p) {
1968*6777b538SAndroid Build Coastguard Worker return p != nullptr;
1969*6777b538SAndroid Build Coastguard Worker }
1970*6777b538SAndroid Build Coastguard Worker
1971*6777b538SAndroid Build Coastguard Worker class ClassWithWeakPtr {
1972*6777b538SAndroid Build Coastguard Worker public:
1973*6777b538SAndroid Build Coastguard Worker ClassWithWeakPtr() = default;
RawPtrArg(int * p)1974*6777b538SAndroid Build Coastguard Worker void RawPtrArg(int* p) { *p = 123; }
RawRefArg(int & p)1975*6777b538SAndroid Build Coastguard Worker void RawRefArg(int& p) { p = 123; }
GetWeakPtr()1976*6777b538SAndroid Build Coastguard Worker WeakPtr<ClassWithWeakPtr> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
1977*6777b538SAndroid Build Coastguard Worker
1978*6777b538SAndroid Build Coastguard Worker private:
1979*6777b538SAndroid Build Coastguard Worker WeakPtrFactory<ClassWithWeakPtr> weak_factory_{this};
1980*6777b538SAndroid Build Coastguard Worker };
1981*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnretainedNoDanglingPtr)1982*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnretainedNoDanglingPtr) {
1983*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
1984*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(PingPong, Unretained(p));
1985*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(callback).Run(), 3);
1986*6777b538SAndroid Build Coastguard Worker Free(p);
1987*6777b538SAndroid Build Coastguard Worker }
1988*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtr)1989*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtr) {
1990*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
1991*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(MayBeDanglingCheckFn, UnsafeDangling(p));
1992*6777b538SAndroid Build Coastguard Worker Free(p);
1993*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(callback).Run(), true);
1994*6777b538SAndroid Build Coastguard Worker }
1995*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtrWithDummyTrait)1996*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtrWithDummyTrait) {
1997*6777b538SAndroid Build Coastguard Worker raw_ptr<int, RawPtrTraits::kDummyForTest> p =
1998*6777b538SAndroid Build Coastguard Worker Alloc<int, RawPtrTraits::kDummyForTest>(3);
1999*6777b538SAndroid Build Coastguard Worker auto callback =
2000*6777b538SAndroid Build Coastguard Worker BindOnce(MayBeDanglingAndDummyTraitCheckFn, UnsafeDangling(p));
2001*6777b538SAndroid Build Coastguard Worker Free(p);
2002*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(callback).Run(), true);
2003*6777b538SAndroid Build Coastguard Worker }
2004*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtrWithDummyAndDanglingTraits)2005*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest,
2006*6777b538SAndroid Build Coastguard Worker UnsafeDanglingPtrWithDummyAndDanglingTraits) {
2007*6777b538SAndroid Build Coastguard Worker raw_ptr<int, RawPtrTraits::kDummyForTest | RawPtrTraits::kMayDangle> p =
2008*6777b538SAndroid Build Coastguard Worker Alloc<int, RawPtrTraits::kDummyForTest | RawPtrTraits::kMayDangle>(3);
2009*6777b538SAndroid Build Coastguard Worker auto callback =
2010*6777b538SAndroid Build Coastguard Worker BindOnce(MayBeDanglingAndDummyTraitCheckFn, UnsafeDangling(p));
2011*6777b538SAndroid Build Coastguard Worker Free(p);
2012*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(callback).Run(), true);
2013*6777b538SAndroid Build Coastguard Worker }
2014*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingPtrNoRawPtrReceiver)2015*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnsafeDanglingPtrNoRawPtrReceiver) {
2016*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2017*6777b538SAndroid Build Coastguard Worker int val = 0;
2018*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(&ClassWithWeakPtr::RawPtrArg,
2019*6777b538SAndroid Build Coastguard Worker UnsafeDangling(r.get()), Unretained(&val));
2020*6777b538SAndroid Build Coastguard Worker std::move(callback).Run();
2021*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(val, 123);
2022*6777b538SAndroid Build Coastguard Worker }
2023*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnsafeDanglingUntriagedPtr)2024*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnsafeDanglingUntriagedPtr) {
2025*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2026*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(PtrCheckFn, UnsafeDanglingUntriaged(p));
2027*6777b538SAndroid Build Coastguard Worker Free(p);
2028*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(callback).Run(), true);
2029*6777b538SAndroid Build Coastguard Worker }
2030*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnretainedWeakReceiverValidNoDangling)2031*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnretainedWeakReceiverValidNoDangling) {
2032*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2033*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2034*6777b538SAndroid Build Coastguard Worker auto callback =
2035*6777b538SAndroid Build Coastguard Worker BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(), Unretained(p));
2036*6777b538SAndroid Build Coastguard Worker std::move(callback).Run();
2037*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(*p, 123);
2038*6777b538SAndroid Build Coastguard Worker Free(p);
2039*6777b538SAndroid Build Coastguard Worker }
2040*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnretainedRefWeakReceiverValidNoDangling)2041*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnretainedRefWeakReceiverValidNoDangling) {
2042*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2043*6777b538SAndroid Build Coastguard Worker int& ref = *p;
2044*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2045*6777b538SAndroid Build Coastguard Worker auto callback =
2046*6777b538SAndroid Build Coastguard Worker BindOnce(&ClassWithWeakPtr::RawRefArg, r->GetWeakPtr(), std::ref(ref));
2047*6777b538SAndroid Build Coastguard Worker std::move(callback).Run();
2048*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(*p, 123);
2049*6777b538SAndroid Build Coastguard Worker Free(p);
2050*6777b538SAndroid Build Coastguard Worker }
2051*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnretainedWeakReceiverInvalidNoDangling)2052*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnretainedWeakReceiverInvalidNoDangling) {
2053*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2054*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2055*6777b538SAndroid Build Coastguard Worker auto callback =
2056*6777b538SAndroid Build Coastguard Worker BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(), Unretained(p));
2057*6777b538SAndroid Build Coastguard Worker r.reset();
2058*6777b538SAndroid Build Coastguard Worker Free(p);
2059*6777b538SAndroid Build Coastguard Worker std::move(callback).Run();
2060*6777b538SAndroid Build Coastguard Worker // Should reach this point without crashing; there is a dangling pointer, but
2061*6777b538SAndroid Build Coastguard Worker // the callback is cancelled because the WeakPtr is already invalidated.
2062*6777b538SAndroid Build Coastguard Worker }
2063*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnretainedRefWeakReceiverInvalidNoDangling)2064*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnretainedRefWeakReceiverInvalidNoDangling) {
2065*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2066*6777b538SAndroid Build Coastguard Worker int& ref = *p;
2067*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2068*6777b538SAndroid Build Coastguard Worker auto callback =
2069*6777b538SAndroid Build Coastguard Worker BindOnce(&ClassWithWeakPtr::RawRefArg, r->GetWeakPtr(), std::ref(ref));
2070*6777b538SAndroid Build Coastguard Worker r.reset();
2071*6777b538SAndroid Build Coastguard Worker Free(p);
2072*6777b538SAndroid Build Coastguard Worker std::move(callback).Run();
2073*6777b538SAndroid Build Coastguard Worker // Should reach this point without crashing; there is a dangling pointer, but
2074*6777b538SAndroid Build Coastguard Worker // the callback is cancelled because the WeakPtr is already invalidated.
2075*6777b538SAndroid Build Coastguard Worker }
2076*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnretainedRefUnsafeDangling)2077*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnretainedRefUnsafeDangling) {
2078*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2079*6777b538SAndroid Build Coastguard Worker int& ref = *p;
2080*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(RefCheckFn, UnsafeDangling(raw_ref<int>(ref)));
2081*6777b538SAndroid Build Coastguard Worker Free(p);
2082*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(callback).Run(), true);
2083*6777b538SAndroid Build Coastguard Worker // Should reach this point without crashing; there is a dangling pointer, but
2084*6777b538SAndroid Build Coastguard Worker // the we marked the reference as `UnsafeDangling`.
2085*6777b538SAndroid Build Coastguard Worker }
2086*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingTest,UnretainedRefUnsafeDanglingUntriaged)2087*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingTest, UnretainedRefUnsafeDanglingUntriaged) {
2088*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2089*6777b538SAndroid Build Coastguard Worker int& ref = *p;
2090*6777b538SAndroid Build Coastguard Worker auto callback =
2091*6777b538SAndroid Build Coastguard Worker BindOnce(RefCheckFn, UnsafeDanglingUntriaged(raw_ref<const int>(ref)));
2092*6777b538SAndroid Build Coastguard Worker Free(p);
2093*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(std::move(callback).Run(), true);
2094*6777b538SAndroid Build Coastguard Worker // Should reach this point without crashing; there is a dangling pointer, but
2095*6777b538SAndroid Build Coastguard Worker // the we marked the reference as `UnsafeDanglingUntriaged`.
2096*6777b538SAndroid Build Coastguard Worker }
2097*6777b538SAndroid Build Coastguard Worker
2098*6777b538SAndroid Build Coastguard Worker // Death tests misbehave on Android, http://crbug.com/643760.
2099*6777b538SAndroid Build Coastguard Worker #if defined(GTEST_HAS_DEATH_TEST) && !BUILDFLAG(IS_ANDROID)
2100*6777b538SAndroid Build Coastguard Worker
FuncWithRefArgument(int & i_ptr)2101*6777b538SAndroid Build Coastguard Worker int FuncWithRefArgument(int& i_ptr) {
2102*6777b538SAndroid Build Coastguard Worker return i_ptr;
2103*6777b538SAndroid Build Coastguard Worker }
2104*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingDeathTest,UnretainedDanglingPtr)2105*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingDeathTest, UnretainedDanglingPtr) {
2106*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2107*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(PingPong, Unretained(p));
2108*6777b538SAndroid Build Coastguard Worker Free(p);
2109*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(std::move(callback).Run(), "");
2110*6777b538SAndroid Build Coastguard Worker }
2111*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingDeathTest,UnretainedRefDanglingPtr)2112*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingDeathTest, UnretainedRefDanglingPtr) {
2113*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2114*6777b538SAndroid Build Coastguard Worker int& ref = *p;
2115*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(FuncWithRefArgument, std::ref(ref));
2116*6777b538SAndroid Build Coastguard Worker Free(p);
2117*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(std::move(callback).Run(), "");
2118*6777b538SAndroid Build Coastguard Worker }
2119*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingDeathTest,UnretainedRefWithManualUnretainedDanglingPtr)2120*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingDeathTest,
2121*6777b538SAndroid Build Coastguard Worker UnretainedRefWithManualUnretainedDanglingPtr) {
2122*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2123*6777b538SAndroid Build Coastguard Worker int& ref = *p;
2124*6777b538SAndroid Build Coastguard Worker auto callback = BindOnce(FuncWithRefArgument, Unretained(raw_ref<int>(ref)));
2125*6777b538SAndroid Build Coastguard Worker Free(p);
2126*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(std::move(callback).Run(), "");
2127*6777b538SAndroid Build Coastguard Worker }
2128*6777b538SAndroid Build Coastguard Worker
TEST_F(BindUnretainedDanglingDeathTest,UnretainedWeakReceiverDangling)2129*6777b538SAndroid Build Coastguard Worker TEST_F(BindUnretainedDanglingDeathTest, UnretainedWeakReceiverDangling) {
2130*6777b538SAndroid Build Coastguard Worker raw_ptr<int> p = Alloc<int>(3);
2131*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClassWithWeakPtr> r = std::make_unique<ClassWithWeakPtr>();
2132*6777b538SAndroid Build Coastguard Worker auto callback =
2133*6777b538SAndroid Build Coastguard Worker BindOnce(&ClassWithWeakPtr::RawPtrArg, r->GetWeakPtr(), Unretained(p));
2134*6777b538SAndroid Build Coastguard Worker Free(p);
2135*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH(std::move(callback).Run(), "");
2136*6777b538SAndroid Build Coastguard Worker }
2137*6777b538SAndroid Build Coastguard Worker
2138*6777b538SAndroid Build Coastguard Worker #endif // defined(GTEST_HAS_DEATH_TEST) && !BUILDFLAG(IS_ANDROID)
2139*6777b538SAndroid Build Coastguard Worker
2140*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
2141*6777b538SAndroid Build Coastguard Worker
2142*6777b538SAndroid Build Coastguard Worker } // namespace
2143*6777b538SAndroid Build Coastguard Worker } // namespace base
2144