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

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

Issue 6718021: Callback support for unbound reference and array arguments. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleaned up. Created 9 years, 9 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.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 $range ARITY 0..MAX_ARITY 75 $range ARITY 0..MAX_ARITY
76 $for ARITY [[ 76 $for ARITY [[
77 $range ARG 1..ARITY 77 $range ARG 1..ARITY
78 78
79 // Function: Arity $(ARITY). 79 // Function: Arity $(ARITY).
80 template <typename R[[]] 80 template <typename R[[]]
81 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> 81 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
82 struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> { 82 struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> {
83 typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]); 83 typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
84 typedef false_type IsMethod; 84 typedef false_type IsMethod;
85
86 $if ARITY > 0 [[
87
88 // Target type for each bound parameter.
89
90 $for ARG [[
91 typedef X$(ARG) B$(ARG);
92
93 ]] $$ for ARG
94 ]] $$ if ARITY > 0
95
85 }; 96 };
86 97
87 // Method: Arity $(ARITY). 98 // Method: Arity $(ARITY).
88 template <typename R, typename T[[]] 99 template <typename R, typename T[[]]
89 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> 100 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
90 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> { 101 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> {
91 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); 102 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
92 typedef true_type IsMethod; 103 typedef true_type IsMethod;
104
105 // Target type for each bound parameter.
106 typedef T B1;
107
108 $for ARG [[
109 typedef X$(ARG) B$(ARG + 1);
110
111 ]] $$ for ARG
112
93 }; 113 };
94 114
95 // Const Method: Arity $(ARITY). 115 // Const Method: Arity $(ARITY).
96 template <typename R, typename T[[]] 116 template <typename R, typename T[[]]
97 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]> 117 $if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
98 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> { 118 struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> {
99 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]); 119 typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
100 typedef true_type IsMethod; 120 typedef true_type IsMethod;
121
122 // Target type for each bound parameter.
123 typedef T B1;
124
125 $for ARG [[
126 typedef X$(ARG) B$(ARG + 1);
127
128 ]] $$ for ARG
129
101 }; 130 };
102 131
103 ]] $$for ARITY 132 ]] $$for ARITY
104 133
105 // InvokerN<> 134 // InvokerN<>
106 // 135 //
107 // The InvokerN templates contain a static DoInvoke() function that is the key 136 // The InvokerN templates contain a static DoInvoke() function that is the key
108 // to implementing type erasure in the Callback() classes. 137 // to implementing type erasure in the Callback() classes.
109 // 138 //
110 // DoInvoke() is a static function with a fixed signature that is independent 139 // DoInvoke() is a static function with a fixed signature that is independent
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 $var M_ARITY = ARITY - 1 173 $var M_ARITY = ARITY - 1
145 $range M_ARG 1..M_ARITY 174 $range M_ARG 1..M_ARITY
146 $range M_BOUND_ARG 2..BOUND 175 $range M_BOUND_ARG 2..BOUND
147 $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY 176 $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY
148 177
149 // Function: Arity $(ARITY) -> $(UNBOUND). 178 // Function: Arity $(ARITY) -> $(UNBOUND).
150 template <typename StorageType, typename R[[]] 179 template <typename StorageType, typename R[[]]
151 $if ARITY > 0 [[,]][[]] 180 $if ARITY > 0 [[,]][[]]
152 $for ARG , [[typename X$(ARG)]]> 181 $for ARG , [[typename X$(ARG)]]>
153 struct Invoker$(BOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> { 182 struct Invoker$(BOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> {
154 $if ARITY > 0 [[
155
156 COMPILE_ASSERT(
157 !($for ARG || [[ is_non_const_reference<X$(ARG)>::value ]]),
158 do_not_bind_functions_with_nonconst_ref);
159
160 ]]
161
162 static R DoInvoke(InvokerStorageBase* base[[]] 183 static R DoInvoke(InvokerStorageBase* base[[]]
163 $if UNBOUND != 0 [[, ]][[]] 184 $if UNBOUND != 0 [[, ]][[]]
164 $for UNBOUND_ARG , [[const X$(UNBOUND_ARG)& x$(UNBOUND_ARG)]]) { 185 $for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardTyp e x$(UNBOUND_ARG)]]) {
165 StorageType* invoker = static_cast<StorageType*>(base); 186 StorageType* invoker = static_cast<StorageType*>(base);
166 return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]] 187 return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]]
167 $$ Add comma if there are both boudn and unbound args. 188 $$ Add comma if there are both boudn and unbound args.
168 $if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]] 189 $if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]]
169 $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]); 190 $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]);
170 } 191 }
171 }; 192 };
172 193
173 $if BOUND > 0 [[ 194 $if BOUND > 0 [[
174 195
175 // Method: Arity $(M_ARITY) -> $(UNBOUND). 196 // Method: Arity $(M_ARITY) -> $(UNBOUND).
176 template <typename StorageType, typename R, typename T[[]] 197 template <typename StorageType, typename R, typename T[[]]
177 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> 198 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
178 struct Invoker$(BOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> { 199 struct Invoker$(BOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
179 $if M_ARITY > 0 [[
180
181 COMPILE_ASSERT(
182 !($for M_ARG || [[ is_non_const_reference<X$(M_ARG)>::value ]]),
183 do_not_bind_functions_with_nonconst_ref);
184
185 ]]
186
187 static R DoInvoke(InvokerStorageBase* base[[]] 200 static R DoInvoke(InvokerStorageBase* base[[]]
188 $if UNBOUND > 0 [[, ]][[]] 201 $if UNBOUND > 0 [[, ]][[]]
189 $for M_UNBOUND_ARG , [[const X$(M_UNBOUND_ARG)& x$(M_UNBOUND_ARG)]]) { 202 $for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::Forwar dType x$(M_UNBOUND_ARG)]]) {
190 StorageType* invoker = static_cast<StorageType*>(base); 203 StorageType* invoker = static_cast<StorageType*>(base);
191 return (Unwrap(invoker->p1_)->*invoker->f_)([[]] 204 return (Unwrap(invoker->p1_)->*invoker->f_)([[]]
192 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] 205 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
193 $if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]] 206 $if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
194 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); 207 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
195 } 208 }
196 }; 209 };
197 210
198 ]] $$ if BOUND 211 ]] $$ if BOUND
199 212
(...skipping 21 matching lines...) Expand all
221 234
222 template <typename Sig[[]] 235 template <typename Sig[[]]
223 $if BOUND > 0 [[, ]] 236 $if BOUND > 0 [[, ]]
224 $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> 237 $for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
225 class InvokerStorage$(BOUND) : public InvokerStorageBase { 238 class InvokerStorage$(BOUND) : public InvokerStorageBase {
226 public: 239 public:
227 typedef InvokerStorage$(BOUND) StorageType; 240 typedef InvokerStorage$(BOUND) StorageType;
228 typedef FunctionTraits<Sig> TargetTraits; 241 typedef FunctionTraits<Sig> TargetTraits;
229 typedef Invoker$(BOUND)<StorageType, typename TargetTraits::NormalizedSig> Inv oker; 242 typedef Invoker$(BOUND)<StorageType, typename TargetTraits::NormalizedSig> Inv oker;
230 typedef typename TargetTraits::IsMethod IsMethod; 243 typedef typename TargetTraits::IsMethod IsMethod;
244
231 $for BOUND_ARG [[ 245 $for BOUND_ARG [[
232 $if BOUND_ARG == 1 [[ 246 $if BOUND_ARG == 1 [[
233 247
234 // For methods, we need to be careful for parameter 1. We skip the 248 // For methods, we need to be careful for parameter 1. We skip the
235 // scoped_refptr check because the binder itself takes care of this. We also 249 // scoped_refptr check because the binder itself takes care of this. We also
236 // disallow binding of an array as the method's target object. 250 // disallow binding of an array as the method's target object.
237 COMPILE_ASSERT(IsMethod::value || 251 COMPILE_ASSERT(IsMethod::value ||
238 !internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value, 252 !internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value,
239 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); 253 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr);
240 COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value, 254 COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value,
241 first_bound_argument_to_method_cannot_be_array); 255 first_bound_argument_to_method_cannot_be_array);
242 ]] $else [[ 256 ]] $else [[
243 257
244 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value, 258 COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value,
245 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr); 259 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr);
246 ]] $$ $if BOUND_ARG 260 ]] $$ $if BOUND_ARG
247 ]] $$ $for BOUND_ARG 261 ]] $$ $for BOUND_ARG
248 262
249 263
264 $if BOUND > 0 [[
265
266 // Do not allow binding a non-const reference parameter. Non-const reference
267 // parameters are disallowed by the Google style guide. Also, binding a
268 // non-const reference parameter can make for subtle bugs because the
269 // invoked function will receive a reference to the stored copy of the
270 // argument and not the original.
271 COMPILE_ASSERT(
272 !($for BOUND_ARG || [[ is_non_const_reference<typename TargetTraits::B$(BO UND_ARG)>::value ]]),
273 do_not_bind_functions_with_nonconst_ref);
274
275 ]]
276
250 277
251 InvokerStorage$(BOUND)(Sig f 278 InvokerStorage$(BOUND)(Sig f
252 $if BOUND > 0 [[, ]] 279 $if BOUND > 0 [[, ]]
253 $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) 280 $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]])
254 : f_(f)[[]] 281 : f_(f)[[]]
255 $if BOUND == 0 [[ 282 $if BOUND == 0 [[
256 { 283 {
257 284
258 ]] $else [[ 285 ]] $else [[
259 , $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename BindType<P$(BOUND_ARG)> ::StorageType>(p$(BOUND_ARG)))]] { 286 , $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename ParamTraits<P$(BOUND_AR G)>::StorageType>(p$(BOUND_ARG)))]] {
260 MaybeRefcount<IsMethod, P1>::AddRef(p1_); 287 MaybeRefcount<IsMethod, P1>::AddRef(p1_);
261 288
262 ]] 289 ]]
263 } 290 }
264 291
265 virtual ~InvokerStorage$(BOUND)() { 292 virtual ~InvokerStorage$(BOUND)() {
266 $if BOUND > 0 [[ 293 $if BOUND > 0 [[
267 294
268 MaybeRefcount<IsMethod, P1>::Release(p1_); 295 MaybeRefcount<IsMethod, P1>::Release(p1_);
269 296
270 ]] 297 ]]
271 } 298 }
272 299
273 Sig f_; 300 Sig f_;
274 301
275 $for BOUND_ARG [[ 302 $for BOUND_ARG [[
276 typename BindType<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_; 303 typename ParamTraits<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_;
277 304
278 ]] 305 ]]
279 }; 306 };
280 307
281 ]] $$ for BOUND 308 ]] $$ for BOUND
282 309
283 } // namespace internal 310 } // namespace internal
284 } // namespace base 311 } // namespace base
285 312
286 #endif // BASE_BIND_INTERNAL_H_ 313 #endif // BASE_BIND_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/bind_internal.h ('k') | base/bind_internal_win.h » ('j') | base/callback_internal.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698