xref: /aosp_15_r20/external/cronet/base/functional/bind_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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