blob: b14f70c109f777ef78991990aedef270a2e82bc8 [file] [log] [blame]
ajwong@chromium.orge2cca632011-02-15 10:27:38 +09001// This file was GENERATED by command:
2// pump.py bind.h.pump
3// DO NOT EDIT BY HAND!!!
4
5
6// Copyright (c) 2011 The Chromium Authors. All rights reserved.
7// Use of this source code is governed by a BSD-style license that can be
8// found in the LICENSE file.
9
10#ifndef BASE_BIND_H_
11#define BASE_BIND_H_
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090012
13#include "base/bind_internal.h"
ajwong@chromium.orgfa0ff432011-02-19 08:29:31 +090014#include "base/callback_internal.h"
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090015
brettw@chromium.org11e3bfd2012-07-13 05:06:40 +090016// -----------------------------------------------------------------------------
17// Usage documentation
18// -----------------------------------------------------------------------------
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090019//
brettw@chromium.org11e3bfd2012-07-13 05:06:40 +090020// See base/callback.h for documentation.
21//
22//
23// -----------------------------------------------------------------------------
24// Implementation notes
25// -----------------------------------------------------------------------------
26//
27// If you're reading the implementation, before proceeding further, you should
28// read the top comment of base/bind_internal.h for a definition of common
29// terms and concepts.
30//
31// RETURN TYPES
32//
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090033// Though Bind()'s result is meant to be stored in a Callback<> type, it
34// cannot actually return the exact type without requiring a large amount
35// of extra template specializations. The problem is that in order to
36// discern the correct specialization of Callback<>, Bind would need to
37// unwrap the function signature to determine the signature's arity, and
38// whether or not it is a method.
39//
40// Each unique combination of (arity, function_type, num_prebound) where
41// function_type is one of {function, method, const_method} would require
42// one specialization. We eventually have to do a similar number of
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090043// specializations anyways in the implementation (see the Invoker<>,
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090044// classes). However, it is avoidable in Bind if we return the result
45// via an indirection like we do below.
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090046//
47// TODO(ajwong): We might be able to avoid this now, but need to test.
48//
49// It is possible to move most of the COMPILE_ASSERT asserts into BindState<>,
50// but it feels a little nicer to have the asserts here so people do not
51// need to crack open bind_internal.h. On the other hand, it makes Bind()
52// harder to read.
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090053
54namespace base {
55
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090056template <typename Functor>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +090057base::Callback<
58 typename internal::BindState<
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090059 typename internal::FunctorTraits<Functor>::RunnableType,
60 typename internal::FunctorTraits<Functor>::RunType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +090061 void()>
62 ::UnboundRunType>
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090063Bind(Functor functor) {
64 // Typedefs for how to store and run the functor.
65 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
66 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
67
ajwong@chromium.orgabd70002011-12-20 09:10:04 +090068 typedef internal::BindState<RunnableType, RunType, void()> BindState;
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090069
ajwong@chromium.orgabd70002011-12-20 09:10:04 +090070
71 return Callback<typename BindState::UnboundRunType>(
72 new BindState(internal::MakeRunnable(functor)));
ajwong@chromium.orge2cca632011-02-15 10:27:38 +090073}
74
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090075template <typename Functor, typename P1>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +090076base::Callback<
77 typename internal::BindState<
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090078 typename internal::FunctorTraits<Functor>::RunnableType,
79 typename internal::FunctorTraits<Functor>::RunType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +090080 void(typename internal::CallbackParamTraits<P1>::StorageType)>
81 ::UnboundRunType>
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +090082Bind(Functor functor, const P1& p1) {
83 // Typedefs for how to store and run the functor.
84 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
85 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
86
87 // Use RunnableType::RunType instead of RunType above because our
88 // checks should below for bound references need to know what the actual
89 // functor is going to interpret the argument as.
90 typedef internal::FunctionTraits<typename RunnableType::RunType>
91 BoundFunctorTraits;
92
93 // Do not allow binding a non-const reference parameter. Non-const reference
94 // parameters are disallowed by the Google style guide. Also, binding a
95 // non-const reference parameter can make for subtle bugs because the
96 // invoked function will receive a reference to the stored copy of the
97 // argument and not the original.
98 COMPILE_ASSERT(
99 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ),
100 do_not_bind_functions_with_nonconst_ref);
101
102 // For methods, we need to be careful for parameter 1. We do not require
103 // a scoped_refptr because BindState<> itself takes care of AddRef() for
104 // methods. We also disallow binding of an array as the method's target
105 // object.
106 COMPILE_ASSERT(
107 internal::HasIsMethodTag<RunnableType>::value ||
108 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
109 p1_is_refcounted_type_and_needs_scoped_refptr);
110 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
111 !is_array<P1>::value,
112 first_bound_argument_to_method_cannot_be_array);
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900113 typedef internal::BindState<RunnableType, RunType,
114 void(typename internal::CallbackParamTraits<P1>::StorageType)> BindState;
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900115
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900116
117 return Callback<typename BindState::UnboundRunType>(
118 new BindState(internal::MakeRunnable(functor), p1));
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900119}
120
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900121template <typename Functor, typename P1, typename P2>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900122base::Callback<
123 typename internal::BindState<
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900124 typename internal::FunctorTraits<Functor>::RunnableType,
125 typename internal::FunctorTraits<Functor>::RunType,
126 void(typename internal::CallbackParamTraits<P1>::StorageType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900127 typename internal::CallbackParamTraits<P2>::StorageType)>
128 ::UnboundRunType>
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900129Bind(Functor functor, const P1& p1, const P2& p2) {
130 // Typedefs for how to store and run the functor.
131 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
132 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
133
134 // Use RunnableType::RunType instead of RunType above because our
135 // checks should below for bound references need to know what the actual
136 // functor is going to interpret the argument as.
137 typedef internal::FunctionTraits<typename RunnableType::RunType>
138 BoundFunctorTraits;
139
140 // Do not allow binding a non-const reference parameter. Non-const reference
141 // parameters are disallowed by the Google style guide. Also, binding a
142 // non-const reference parameter can make for subtle bugs because the
143 // invoked function will receive a reference to the stored copy of the
144 // argument and not the original.
145 COMPILE_ASSERT(
146 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
147 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ),
148 do_not_bind_functions_with_nonconst_ref);
149
150 // For methods, we need to be careful for parameter 1. We do not require
151 // a scoped_refptr because BindState<> itself takes care of AddRef() for
152 // methods. We also disallow binding of an array as the method's target
153 // object.
154 COMPILE_ASSERT(
155 internal::HasIsMethodTag<RunnableType>::value ||
156 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
157 p1_is_refcounted_type_and_needs_scoped_refptr);
158 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
159 !is_array<P1>::value,
160 first_bound_argument_to_method_cannot_be_array);
161 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
162 p2_is_refcounted_type_and_needs_scoped_refptr);
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900163 typedef internal::BindState<RunnableType, RunType,
164 void(typename internal::CallbackParamTraits<P1>::StorageType,
165 typename internal::CallbackParamTraits<P2>::StorageType)> BindState;
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900166
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900167
168 return Callback<typename BindState::UnboundRunType>(
169 new BindState(internal::MakeRunnable(functor), p1, p2));
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900170}
171
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900172template <typename Functor, typename P1, typename P2, typename P3>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900173base::Callback<
174 typename internal::BindState<
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900175 typename internal::FunctorTraits<Functor>::RunnableType,
176 typename internal::FunctorTraits<Functor>::RunType,
177 void(typename internal::CallbackParamTraits<P1>::StorageType,
178 typename internal::CallbackParamTraits<P2>::StorageType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900179 typename internal::CallbackParamTraits<P3>::StorageType)>
180 ::UnboundRunType>
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900181Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) {
182 // Typedefs for how to store and run the functor.
183 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
184 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
185
186 // Use RunnableType::RunType instead of RunType above because our
187 // checks should below for bound references need to know what the actual
188 // functor is going to interpret the argument as.
189 typedef internal::FunctionTraits<typename RunnableType::RunType>
190 BoundFunctorTraits;
191
192 // Do not allow binding a non-const reference parameter. Non-const reference
193 // parameters are disallowed by the Google style guide. Also, binding a
194 // non-const reference parameter can make for subtle bugs because the
195 // invoked function will receive a reference to the stored copy of the
196 // argument and not the original.
197 COMPILE_ASSERT(
198 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
199 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
200 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ),
201 do_not_bind_functions_with_nonconst_ref);
202
203 // For methods, we need to be careful for parameter 1. We do not require
204 // a scoped_refptr because BindState<> itself takes care of AddRef() for
205 // methods. We also disallow binding of an array as the method's target
206 // object.
207 COMPILE_ASSERT(
208 internal::HasIsMethodTag<RunnableType>::value ||
209 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
210 p1_is_refcounted_type_and_needs_scoped_refptr);
211 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
212 !is_array<P1>::value,
213 first_bound_argument_to_method_cannot_be_array);
214 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
215 p2_is_refcounted_type_and_needs_scoped_refptr);
216 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
217 p3_is_refcounted_type_and_needs_scoped_refptr);
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900218 typedef internal::BindState<RunnableType, RunType,
219 void(typename internal::CallbackParamTraits<P1>::StorageType,
220 typename internal::CallbackParamTraits<P2>::StorageType,
221 typename internal::CallbackParamTraits<P3>::StorageType)> BindState;
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900222
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900223
224 return Callback<typename BindState::UnboundRunType>(
225 new BindState(internal::MakeRunnable(functor), p1, p2, p3));
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900226}
227
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900228template <typename Functor, typename P1, typename P2, typename P3, typename P4>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900229base::Callback<
230 typename internal::BindState<
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900231 typename internal::FunctorTraits<Functor>::RunnableType,
232 typename internal::FunctorTraits<Functor>::RunType,
233 void(typename internal::CallbackParamTraits<P1>::StorageType,
234 typename internal::CallbackParamTraits<P2>::StorageType,
235 typename internal::CallbackParamTraits<P3>::StorageType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900236 typename internal::CallbackParamTraits<P4>::StorageType)>
237 ::UnboundRunType>
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900238Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
239 // Typedefs for how to store and run the functor.
240 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
241 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
242
243 // Use RunnableType::RunType instead of RunType above because our
244 // checks should below for bound references need to know what the actual
245 // functor is going to interpret the argument as.
246 typedef internal::FunctionTraits<typename RunnableType::RunType>
247 BoundFunctorTraits;
248
249 // Do not allow binding a non-const reference parameter. Non-const reference
250 // parameters are disallowed by the Google style guide. Also, binding a
251 // non-const reference parameter can make for subtle bugs because the
252 // invoked function will receive a reference to the stored copy of the
253 // argument and not the original.
254 COMPILE_ASSERT(
255 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
256 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
257 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
258 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ),
259 do_not_bind_functions_with_nonconst_ref);
260
261 // For methods, we need to be careful for parameter 1. We do not require
262 // a scoped_refptr because BindState<> itself takes care of AddRef() for
263 // methods. We also disallow binding of an array as the method's target
264 // object.
265 COMPILE_ASSERT(
266 internal::HasIsMethodTag<RunnableType>::value ||
267 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
268 p1_is_refcounted_type_and_needs_scoped_refptr);
269 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
270 !is_array<P1>::value,
271 first_bound_argument_to_method_cannot_be_array);
272 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
273 p2_is_refcounted_type_and_needs_scoped_refptr);
274 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
275 p3_is_refcounted_type_and_needs_scoped_refptr);
276 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
277 p4_is_refcounted_type_and_needs_scoped_refptr);
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900278 typedef internal::BindState<RunnableType, RunType,
279 void(typename internal::CallbackParamTraits<P1>::StorageType,
280 typename internal::CallbackParamTraits<P2>::StorageType,
281 typename internal::CallbackParamTraits<P3>::StorageType,
282 typename internal::CallbackParamTraits<P4>::StorageType)> BindState;
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900283
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900284
285 return Callback<typename BindState::UnboundRunType>(
286 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4));
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900287}
288
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900289template <typename Functor, typename P1, typename P2, typename P3, typename P4,
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900290 typename P5>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900291base::Callback<
292 typename internal::BindState<
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900293 typename internal::FunctorTraits<Functor>::RunnableType,
294 typename internal::FunctorTraits<Functor>::RunType,
295 void(typename internal::CallbackParamTraits<P1>::StorageType,
296 typename internal::CallbackParamTraits<P2>::StorageType,
297 typename internal::CallbackParamTraits<P3>::StorageType,
298 typename internal::CallbackParamTraits<P4>::StorageType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900299 typename internal::CallbackParamTraits<P5>::StorageType)>
300 ::UnboundRunType>
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900301Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900302 const P5& p5) {
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900303 // Typedefs for how to store and run the functor.
304 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
305 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
306
307 // Use RunnableType::RunType instead of RunType above because our
308 // checks should below for bound references need to know what the actual
309 // functor is going to interpret the argument as.
310 typedef internal::FunctionTraits<typename RunnableType::RunType>
311 BoundFunctorTraits;
312
313 // Do not allow binding a non-const reference parameter. Non-const reference
314 // parameters are disallowed by the Google style guide. Also, binding a
315 // non-const reference parameter can make for subtle bugs because the
316 // invoked function will receive a reference to the stored copy of the
317 // argument and not the original.
318 COMPILE_ASSERT(
319 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
320 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
321 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
322 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
323 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ),
324 do_not_bind_functions_with_nonconst_ref);
325
326 // For methods, we need to be careful for parameter 1. We do not require
327 // a scoped_refptr because BindState<> itself takes care of AddRef() for
328 // methods. We also disallow binding of an array as the method's target
329 // object.
330 COMPILE_ASSERT(
331 internal::HasIsMethodTag<RunnableType>::value ||
332 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
333 p1_is_refcounted_type_and_needs_scoped_refptr);
334 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
335 !is_array<P1>::value,
336 first_bound_argument_to_method_cannot_be_array);
337 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
338 p2_is_refcounted_type_and_needs_scoped_refptr);
339 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
340 p3_is_refcounted_type_and_needs_scoped_refptr);
341 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
342 p4_is_refcounted_type_and_needs_scoped_refptr);
343 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
344 p5_is_refcounted_type_and_needs_scoped_refptr);
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900345 typedef internal::BindState<RunnableType, RunType,
346 void(typename internal::CallbackParamTraits<P1>::StorageType,
347 typename internal::CallbackParamTraits<P2>::StorageType,
348 typename internal::CallbackParamTraits<P3>::StorageType,
349 typename internal::CallbackParamTraits<P4>::StorageType,
350 typename internal::CallbackParamTraits<P5>::StorageType)> BindState;
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900351
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900352
353 return Callback<typename BindState::UnboundRunType>(
354 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5));
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900355}
356
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900357template <typename Functor, typename P1, typename P2, typename P3, typename P4,
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900358 typename P5, typename P6>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900359base::Callback<
360 typename internal::BindState<
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900361 typename internal::FunctorTraits<Functor>::RunnableType,
362 typename internal::FunctorTraits<Functor>::RunType,
363 void(typename internal::CallbackParamTraits<P1>::StorageType,
364 typename internal::CallbackParamTraits<P2>::StorageType,
365 typename internal::CallbackParamTraits<P3>::StorageType,
366 typename internal::CallbackParamTraits<P4>::StorageType,
367 typename internal::CallbackParamTraits<P5>::StorageType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900368 typename internal::CallbackParamTraits<P6>::StorageType)>
369 ::UnboundRunType>
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900370Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900371 const P5& p5, const P6& p6) {
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900372 // Typedefs for how to store and run the functor.
373 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
374 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900375
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900376 // Use RunnableType::RunType instead of RunType above because our
377 // checks should below for bound references need to know what the actual
378 // functor is going to interpret the argument as.
379 typedef internal::FunctionTraits<typename RunnableType::RunType>
380 BoundFunctorTraits;
ajwong@chromium.orgd483ffe2011-09-30 18:09:34 +0900381
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900382 // Do not allow binding a non-const reference parameter. Non-const reference
383 // parameters are disallowed by the Google style guide. Also, binding a
384 // non-const reference parameter can make for subtle bugs because the
385 // invoked function will receive a reference to the stored copy of the
386 // argument and not the original.
387 COMPILE_ASSERT(
388 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
389 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
390 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
391 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
392 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
393 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ),
394 do_not_bind_functions_with_nonconst_ref);
ajwong@chromium.orgd483ffe2011-09-30 18:09:34 +0900395
ajwong@chromium.orgc9c79af2011-11-22 04:23:44 +0900396 // For methods, we need to be careful for parameter 1. We do not require
397 // a scoped_refptr because BindState<> itself takes care of AddRef() for
398 // methods. We also disallow binding of an array as the method's target
399 // object.
400 COMPILE_ASSERT(
401 internal::HasIsMethodTag<RunnableType>::value ||
402 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
403 p1_is_refcounted_type_and_needs_scoped_refptr);
404 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
405 !is_array<P1>::value,
406 first_bound_argument_to_method_cannot_be_array);
407 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
408 p2_is_refcounted_type_and_needs_scoped_refptr);
409 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
410 p3_is_refcounted_type_and_needs_scoped_refptr);
411 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
412 p4_is_refcounted_type_and_needs_scoped_refptr);
413 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
414 p5_is_refcounted_type_and_needs_scoped_refptr);
415 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
416 p6_is_refcounted_type_and_needs_scoped_refptr);
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900417 typedef internal::BindState<RunnableType, RunType,
418 void(typename internal::CallbackParamTraits<P1>::StorageType,
419 typename internal::CallbackParamTraits<P2>::StorageType,
420 typename internal::CallbackParamTraits<P3>::StorageType,
421 typename internal::CallbackParamTraits<P4>::StorageType,
422 typename internal::CallbackParamTraits<P5>::StorageType,
423 typename internal::CallbackParamTraits<P6>::StorageType)> BindState;
ajwong@chromium.orgd483ffe2011-09-30 18:09:34 +0900424
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900425
426 return Callback<typename BindState::UnboundRunType>(
427 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6));
ajwong@chromium.orgd483ffe2011-09-30 18:09:34 +0900428}
429
ajwong@chromium.org6f015bd2011-11-29 07:13:54 +0900430template <typename Functor, typename P1, typename P2, typename P3, typename P4,
431 typename P5, typename P6, typename P7>
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900432base::Callback<
433 typename internal::BindState<
ajwong@chromium.org6f015bd2011-11-29 07:13:54 +0900434 typename internal::FunctorTraits<Functor>::RunnableType,
435 typename internal::FunctorTraits<Functor>::RunType,
436 void(typename internal::CallbackParamTraits<P1>::StorageType,
437 typename internal::CallbackParamTraits<P2>::StorageType,
438 typename internal::CallbackParamTraits<P3>::StorageType,
439 typename internal::CallbackParamTraits<P4>::StorageType,
440 typename internal::CallbackParamTraits<P5>::StorageType,
441 typename internal::CallbackParamTraits<P6>::StorageType,
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900442 typename internal::CallbackParamTraits<P7>::StorageType)>
443 ::UnboundRunType>
ajwong@chromium.org6f015bd2011-11-29 07:13:54 +0900444Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
445 const P5& p5, const P6& p6, const P7& p7) {
446 // Typedefs for how to store and run the functor.
447 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
448 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
449
450 // Use RunnableType::RunType instead of RunType above because our
451 // checks should below for bound references need to know what the actual
452 // functor is going to interpret the argument as.
453 typedef internal::FunctionTraits<typename RunnableType::RunType>
454 BoundFunctorTraits;
455
456 // Do not allow binding a non-const reference parameter. Non-const reference
457 // parameters are disallowed by the Google style guide. Also, binding a
458 // non-const reference parameter can make for subtle bugs because the
459 // invoked function will receive a reference to the stored copy of the
460 // argument and not the original.
461 COMPILE_ASSERT(
462 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
463 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
464 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
465 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
466 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
467 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ||
468 is_non_const_reference<typename BoundFunctorTraits::A7Type>::value ),
469 do_not_bind_functions_with_nonconst_ref);
470
471 // For methods, we need to be careful for parameter 1. We do not require
472 // a scoped_refptr because BindState<> itself takes care of AddRef() for
473 // methods. We also disallow binding of an array as the method's target
474 // object.
475 COMPILE_ASSERT(
476 internal::HasIsMethodTag<RunnableType>::value ||
477 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
478 p1_is_refcounted_type_and_needs_scoped_refptr);
479 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
480 !is_array<P1>::value,
481 first_bound_argument_to_method_cannot_be_array);
482 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
483 p2_is_refcounted_type_and_needs_scoped_refptr);
484 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
485 p3_is_refcounted_type_and_needs_scoped_refptr);
486 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
487 p4_is_refcounted_type_and_needs_scoped_refptr);
488 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
489 p5_is_refcounted_type_and_needs_scoped_refptr);
490 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
491 p6_is_refcounted_type_and_needs_scoped_refptr);
492 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P7>::value,
493 p7_is_refcounted_type_and_needs_scoped_refptr);
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900494 typedef internal::BindState<RunnableType, RunType,
495 void(typename internal::CallbackParamTraits<P1>::StorageType,
496 typename internal::CallbackParamTraits<P2>::StorageType,
497 typename internal::CallbackParamTraits<P3>::StorageType,
498 typename internal::CallbackParamTraits<P4>::StorageType,
499 typename internal::CallbackParamTraits<P5>::StorageType,
500 typename internal::CallbackParamTraits<P6>::StorageType,
501 typename internal::CallbackParamTraits<P7>::StorageType)> BindState;
ajwong@chromium.org6f015bd2011-11-29 07:13:54 +0900502
ajwong@chromium.orgabd70002011-12-20 09:10:04 +0900503
504 return Callback<typename BindState::UnboundRunType>(
505 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6,
506 p7));
ajwong@chromium.org6f015bd2011-11-29 07:13:54 +0900507}
508
ajwong@chromium.orge2cca632011-02-15 10:27:38 +0900509} // namespace base
510
511#endif // BASE_BIND_H_