Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: base/bind_internal.h.pump

Issue 7015064: Support binding WeakPtr<> to methods with void return types. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix copyright Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 $$ This is a pump file for generating file templates. Pump is a python 1 $$ This is a pump file for generating file templates. Pump is a python
2 $$ script that is part of the Google Test suite of utilities. Description 2 $$ script that is part of the Google Test suite of utilities. Description
3 $$ can be found here: 3 $$ can be found here:
4 $$ 4 $$
5 $$ http://code.google.com/p/googletest/wiki/PumpManual 5 $$ http://code.google.com/p/googletest/wiki/PumpManual
6 $$ 6 $$
7 7
8 $var MAX_ARITY = 6 8 $var MAX_ARITY = 6
9 9
10 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 10 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
11 // Use of this source code is governed by a BSD-style license that can be 11 // Use of this source code is governed by a BSD-style license that can be
12 // found in the LICENSE file. 12 // found in the LICENSE file.
13 13
14 #ifndef BASE_BIND_INTERNAL_H_ 14 #ifndef BASE_BIND_INTERNAL_H_
15 #define BASE_BIND_INTERNAL_H_ 15 #define BASE_BIND_INTERNAL_H_
16 #pragma once 16 #pragma once
17 17
18 #include "base/bind_helpers.h" 18 #include "base/bind_helpers.h"
19 #include "base/callback_internal.h" 19 #include "base/callback_internal.h"
20 #include "base/template_util.h" 20 #include "base/template_util.h"
21 #include "build/build_config.h" 21 #include "build/build_config.h"
22 #include "base/memory/weak_ptr.h"
22 23
23 #if defined(OS_WIN) 24 #if defined(OS_WIN)
24 #include "base/bind_internal_win.h" 25 #include "base/bind_internal_win.h"
25 #endif 26 #endif
26 27
27 namespace base { 28 namespace base {
28 namespace internal { 29 namespace internal {
29 30
30 // The method by which a function is invoked is determined by 3 different 31 // The method by which a function is invoked is determined by 3 different
31 // dimensions: 32 // dimensions:
32 // 33 //
33 // 1) The type of function (normal or method). 34 // 1) The type of function (normal or method).
34 // 2) The arity of the function. 35 // 2) The arity of the function.
35 // 3) The number of bound parameters. 36 // 3) The number of bound parameters.
36 // 37 //
37 // The templates below handle the determination of each of these dimensions. 38 // The templates below handle the determination of each of these dimensions.
38 // In brief: 39 // In brief:
39 // 40 //
40 // FunctionTraits<> -- Provides a normalied signature, and other traits. 41 // FunctionTraits<> -- Provides a normalied signature, and other traits.
41 // InvokerN<> -- Provides a DoInvoke() function that actually executes 42 // InvokerN<> -- Provides a DoInvoke() function that actually executes
42 // a calback. 43 // a calback.
43 // InvokerStorageN<> -- Provides storage for the bound parameters, and 44 // InvokerStorageN<> -- Provides storage for the bound parameters, and
44 // typedefs to the above. 45 // typedefs to the above.
46 // IsWeakMethod<> -- Determines if we are binding a method to a WeakPtr<>.
45 // 47 //
46 // More details about the design of each class is included in a comment closer 48 // More details about the design of each class is included in a comment closer
47 // to their defition. 49 // to their defition.
48 50
51
52 // IsWeakMethod determines if we are binding a method to a WeakPtr<> for an
53 // object. It is used to select an InvokerN that will no-op itself in the
54 // event the WeakPtr<> for the target object is invalidated.
55 template <bool IsMethod, typename T>
56 struct IsWeakMethod : public false_type {};
57
58 template <typename T>
59 struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};
60
49 // FunctionTraits<> 61 // FunctionTraits<>
50 // 62 //
51 // The FunctionTraits<> template determines the type of function, and also 63 // The FunctionTraits<> template determines the type of function, and also
52 // creates a NormalizedType used to select the InvokerN classes. It turns out 64 // creates a NormalizedType used to select the InvokerN classes. It turns out
53 // that syntactically, you only really have 2 variations when invoking a 65 // that syntactically, you only really have 2 variations when invoking a
54 // funciton pointer: normal, and method. One is invoked func_ptr(arg1). The 66 // funciton pointer: normal, and method. One is invoked func_ptr(arg1). The
55 // other is invoked (*obj_->method_ptr(arg1)). 67 // other is invoked (*obj_->method_ptr(arg1)).
56 // 68 //
57 // However, in the type system, there are many more distinctions. In standard 69 // However, in the type system, there are many more distinctions. In standard
58 // C++, there's all variations of const, and volatile on the function pointer. 70 // C++, there's all variations of const, and volatile on the function pointer.
(...skipping 17 matching lines...) Expand all
76 $for ARITY [[ 88 $for ARITY [[
77 $range ARG 1..ARITY 89 $range ARG 1..ARITY
78 90
79 // Function: Arity $(ARITY). 91 // Function: Arity $(ARITY).
80 template <typename R[[]] 92 template <typename R[[]]
81 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> 93 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
82 struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> { 94 struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> {
83 typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]); 95 typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
84 typedef false_type IsMethod; 96 typedef false_type IsMethod;
85 97
98 typedef R Return;
99
86 $if ARITY > 0 [[ 100 $if ARITY > 0 [[
87 101
88 // Target type for each bound parameter. 102 // Target type for each bound parameter.
89 103
90 $for ARG [[ 104 $for ARG [[
91 typedef X$(ARG) B$(ARG); 105 typedef X$(ARG) B$(ARG);
92 106
93 ]] $$ for ARG 107 ]] $$ for ARG
94 ]] $$ if ARITY > 0 108 ]] $$ if ARITY > 0
95 109
96 }; 110 };
97 111
98 // Method: Arity $(ARITY). 112 // Method: Arity $(ARITY).
99 template <typename R, typename T[[]] 113 template <typename R, typename T[[]]
100 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> 114 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
101 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> { 115 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> {
102 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); 116 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
103 typedef true_type IsMethod; 117 typedef true_type IsMethod;
104 118
119 typedef R Return;
120
105 // Target type for each bound parameter. 121 // Target type for each bound parameter.
106 typedef T B1; 122 typedef T B1;
107 123
108 $for ARG [[ 124 $for ARG [[
109 typedef X$(ARG) B$(ARG + 1); 125 typedef X$(ARG) B$(ARG + 1);
110 126
111 ]] $$ for ARG 127 ]] $$ for ARG
112 128
113 }; 129 };
114 130
115 // Const Method: Arity $(ARITY). 131 // Const Method: Arity $(ARITY).
116 template <typename R, typename T[[]] 132 template <typename R, typename T[[]]
117 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> 133 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
118 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> { 134 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> {
119 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); 135 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
120 typedef true_type IsMethod; 136 typedef true_type IsMethod;
121 137
138 typedef R Return;
139
122 // Target type for each bound parameter. 140 // Target type for each bound parameter.
123 typedef T B1; 141 typedef T B1;
124 142
125 $for ARG [[ 143 $for ARG [[
126 typedef X$(ARG) B$(ARG + 1); 144 typedef X$(ARG) B$(ARG + 1);
127 145
128 ]] $$ for ARG 146 ]] $$ for ARG
129 147
130 }; 148 };
131 149
(...skipping 15 matching lines...) Expand all
147 // safe. 165 // safe.
148 // 166 //
149 // The InvokerN templates are the only point that knows the number of bound 167 // The InvokerN templates are the only point that knows the number of bound
150 // and unbound arguments. This is intentional because it allows the other 168 // and unbound arguments. This is intentional because it allows the other
151 // templates classes in the system to only have as many specializations as 169 // templates classes in the system to only have as many specializations as
152 // the max arity of function we wish to support. 170 // the max arity of function we wish to support.
153 171
154 $range BOUND 0..MAX_ARITY 172 $range BOUND 0..MAX_ARITY
155 $for BOUND [[ 173 $for BOUND [[
156 174
157 template <typename StorageType, typename NormalizedSig> 175 template <bool IsWeak, typename StorageType, typename NormalizedSig>
158 struct Invoker$(BOUND); 176 struct Invoker$(BOUND);
159 177
160 $range ARITY 0..MAX_ARITY 178 $range ARITY 0..MAX_ARITY
161 $for ARITY [[ 179 $for ARITY [[
162 180
163 $var UNBOUND = ARITY - BOUND 181 $var UNBOUND = ARITY - BOUND
164 $if UNBOUND >= 0 [[ 182 $if UNBOUND >= 0 [[
165 183
166 $$ Variables for function traits generation. 184 $$ Variables for function traits generation.
167 $range ARG 1..ARITY 185 $range ARG 1..ARITY
168 $range BOUND_ARG 1..BOUND 186 $range BOUND_ARG 1..BOUND
169 $range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY 187 $range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY
170 188
171 $$ Variables for method traits generation. We are always short one arity since 189 $$ Variables for method traits generation. We are always short one arity since
172 $$ the first bound parameter is the object. 190 $$ the first bound parameter is the object.
173 $var M_ARITY = ARITY - 1 191 $var M_ARITY = ARITY - 1
174 $range M_ARG 1..M_ARITY 192 $range M_ARG 1..M_ARITY
175 $range M_BOUND_ARG 2..BOUND 193 $range M_BOUND_ARG 2..BOUND
176 $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY 194 $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY
177 195
178 // Function: Arity $(ARITY) -> $(UNBOUND). 196 // Function: Arity $(ARITY) -> $(UNBOUND).
179 template <typename StorageType, typename R[[]] 197 template <typename StorageType, typename R[[]]
180 $if ARITY > 0 [[,]][[]] 198 $if ARITY > 0 [[,]][[]]
181 $for ARG , [[typename X$(ARG)]]> 199 $for ARG , [[typename X$(ARG)]]>
182 struct Invoker$(BOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> { 200 struct Invoker$(BOUND)<false, StorageType, R(*)($for ARG , [[X$(ARG)]])> {
183 static R DoInvoke(InvokerStorageBase* base[[]] 201 static R DoInvoke(InvokerStorageBase* base[[]]
184 $if UNBOUND != 0 [[, ]][[]] 202 $if UNBOUND != 0 [[, ]][[]]
185 $for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardTyp e x$(UNBOUND_ARG)]]) { 203 $for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardTyp e x$(UNBOUND_ARG)]]) {
186 StorageType* invoker = static_cast<StorageType*>(base); 204 StorageType* invoker = static_cast<StorageType*>(base);
187 return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]] 205 return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]]
188 $$ Add comma if there are both boudn and unbound args. 206 $$ Add comma if there are both boudn and unbound args.
189 $if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]] 207 $if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]]
190 $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]); 208 $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]);
191 } 209 }
192 }; 210 };
193 211
194 $if BOUND > 0 [[ 212 $if BOUND > 0 [[
195 213
196 // Method: Arity $(M_ARITY) -> $(UNBOUND). 214 // Method: Arity $(M_ARITY) -> $(UNBOUND).
197 template <typename StorageType, typename R, typename T[[]] 215 template <typename StorageType, typename R, typename T[[]]
198 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> 216 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
199 struct Invoker$(BOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> { 217 struct Invoker$(BOUND)<false, StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
200 static R DoInvoke(InvokerStorageBase* base[[]] 218 static R DoInvoke(InvokerStorageBase* base[[]]
201 $if UNBOUND > 0 [[, ]][[]] 219 $if UNBOUND > 0 [[, ]][[]]
202 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar dType x$(M_UNBOUND_ARG)]]) { 220 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar dType x$(M_UNBOUND_ARG)]]) {
203 StorageType* invoker = static_cast<StorageType*>(base); 221 StorageType* invoker = static_cast<StorageType*>(base);
204 return (Unwrap(invoker->p1_)->*invoker->f_)([[]] 222 return (Unwrap(invoker->p1_)->*invoker->f_)([[]]
205 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] 223 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
206 $if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]] 224 $if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
207 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); 225 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
208 } 226 }
209 }; 227 };
210 228
229 // WeakPtr Method: Arity $(M_ARITY) -> $(UNBOUND).
230 template <typename StorageType, typename T[[]]
231 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
232 struct Invoker$(BOUND)<true, StorageType, void(T::*)($for M_ARG , [[X$(M_ARG)]]) > {
233 static void DoInvoke(InvokerStorageBase* base[[]]
234 $if UNBOUND > 0 [[, ]][[]]
235 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar dType x$(M_UNBOUND_ARG)]]) {
236 StorageType* invoker = static_cast<StorageType*>(base);
237 if (!invoker->p1_.get()) {
238 return;
239 }
240 (invoker->p1_->*invoker->f_)([[]]
241 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
242 $if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
243 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
244 }
245 };
246
211 ]] $$ if BOUND 247 ]] $$ if BOUND
212 248
213 ]] $$ if UNBOUND 249 ]] $$ if UNBOUND
214 ]] $$ for ARITY 250 ]] $$ for ARITY
215 ]] $$ for BOUND 251 ]] $$ for BOUND
216 252
217
218 // InvokerStorageN<> 253 // InvokerStorageN<>
219 // 254 //
220 // These are the actual storage classes for the Invokers. 255 // These are the actual storage classes for the Invokers.
221 // 256 //
222 // Though these types are "classes", they are being used as structs with 257 // Though these types are "classes", they are being used as structs with
223 // all member variable public. We cannot make it a struct because it inherits 258 // all member variable public. We cannot make it a struct because it inherits
224 // from a class which causes a compiler warning. We cannot add a "Run()" method 259 // from a class which causes a compiler warning. We cannot add a "Run()" method
225 // that forwards the unbound arguments because that would require we unwrap the 260 // that forwards the unbound arguments because that would require we unwrap the
226 // Sig type like in InvokerN above to know the return type, and the arity 261 // Sig type like in InvokerN above to know the return type, and the arity
227 // of Run(). 262 // of Run().
228 // 263 //
229 // An alternate solution would be to merge InvokerN and InvokerStorageN, 264 // An alternate solution would be to merge InvokerN and InvokerStorageN,
230 // but the generated code seemed harder to read. 265 // but the generated code seemed harder to read.
231 266
232 $for BOUND [[ 267 $for BOUND [[
233 $range BOUND_ARG 1..BOUND 268 $range BOUND_ARG 1..BOUND
234 269
235 template <typename Sig[[]] 270 template <typename Sig[[]]
236 $if BOUND > 0 [[, ]] 271 $if BOUND > 0 [[, ]]
237 $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> 272 $for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
238 class InvokerStorage$(BOUND) : public InvokerStorageBase { 273 class InvokerStorage$(BOUND) : public InvokerStorageBase {
239 public: 274 public:
240 typedef InvokerStorage$(BOUND) StorageType; 275 typedef InvokerStorage$(BOUND) StorageType;
241 typedef FunctionTraits<Sig> TargetTraits; 276 typedef FunctionTraits<Sig> TargetTraits;
242 typedef Invoker$(BOUND)<StorageType, typename TargetTraits::NormalizedSig> Inv oker;
243 typedef typename TargetTraits::IsMethod IsMethod; 277 typedef typename TargetTraits::IsMethod IsMethod;
244 278
279 $if BOUND == 0 [[
280 typedef Invoker$(BOUND)<false, StorageType,
281 typename TargetTraits::NormalizedSig> Invoker;
282 ]] $else [[
283 typedef Invoker$(BOUND)<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
284 typename TargetTraits::NormalizedSig> Invoker;
285 COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
286 is_void<typename TargetTraits::Return>::value,
287 weak_ptrs_can_only_bind_to_methods_without_return_values);
288 ]]
289
290
245 $for BOUND_ARG [[ 291 $for BOUND_ARG [[
246 $if BOUND_ARG == 1 [[ 292 $if BOUND_ARG == 1 [[
247 293
248 // For methods, we need to be careful for parameter 1. We skip the 294 // For methods, we need to be careful for parameter 1. We skip the
249 // scoped_refptr check because the binder itself takes care of this. We also 295 // scoped_refptr check because the binder itself takes care of this. We also
250 // disallow binding of an array as the method's target object. 296 // disallow binding of an array as the method's target object.
251 COMPILE_ASSERT(IsMethod::value || 297 COMPILE_ASSERT(IsMethod::value ||
252 !internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value, 298 !internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value,
253 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); 299 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr);
254 COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value, 300 COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 350
305 ]] 351 ]]
306 }; 352 };
307 353
308 ]] $$ for BOUND 354 ]] $$ for BOUND
309 355
310 } // namespace internal 356 } // namespace internal
311 } // namespace base 357 } // namespace base
312 358
313 #endif // BASE_BIND_INTERNAL_H_ 359 #endif // BASE_BIND_INTERNAL_H_
OLDNEW
« base/bind_internal.h ('K') | « base/bind_internal.h ('k') | base/bind_internal_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698