1 // Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2011
2 // Google Inc. All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the name Chromium Embedded
15 // Framework nor the names of its contributors may be used to endorse
16 // or promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #ifndef CEF_INCLUDE_BASE_CEF_BIND_H_
32 #define CEF_INCLUDE_BASE_CEF_BIND_H_
33 #pragma once
34
35 #if defined(BASE_BIND_H_)
36 // Do nothing if the Chromium header has already been included.
37 // This can happen in cases where Chromium code is used directly by the
38 // client application. When using Chromium code directly always include
39 // the Chromium header first to avoid type conflicts.
40 #elif defined(USING_CHROMIUM_INCLUDES)
41 // When building CEF include the Chromium header directly.
42 #include "base/bind.h"
43 #else // !USING_CHROMIUM_INCLUDES
44 // The following is substantially similar to the Chromium implementation.
45 // If the Chromium implementation diverges the below implementation should be
46 // updated to match.
47
48 #include "include/base/internal/cef_bind_internal.h"
49 #include "include/base/internal/cef_callback_internal.h"
50
51 // -----------------------------------------------------------------------------
52 // Usage documentation
53 // -----------------------------------------------------------------------------
54 //
55 // See base/cef_callback.h for documentation.
56 //
57 //
58 // -----------------------------------------------------------------------------
59 // Implementation notes
60 // -----------------------------------------------------------------------------
61 //
62 // If you're reading the implementation, before proceeding further, you should
63 // read the top comment of base/bind_internal.h for a definition of common
64 // terms and concepts.
65 //
66 // RETURN TYPES
67 //
68 // Though Bind()'s result is meant to be stored in a Callback<> type, it
69 // cannot actually return the exact type without requiring a large amount
70 // of extra template specializations. The problem is that in order to
71 // discern the correct specialization of Callback<>, Bind would need to
72 // unwrap the function signature to determine the signature's arity, and
73 // whether or not it is a method.
74 //
75 // Each unique combination of (arity, function_type, num_prebound) where
76 // function_type is one of {function, method, const_method} would require
77 // one specialization. We eventually have to do a similar number of
78 // specializations anyways in the implementation (see the Invoker<>,
79 // classes). However, it is avoidable in Bind if we return the result
80 // via an indirection like we do below.
81 //
82 // TODO(ajwong): We might be able to avoid this now, but need to test.
83 //
84 // It is possible to move most of the COMPILE_ASSERT asserts into BindState<>,
85 // but it feels a little nicer to have the asserts here so people do not
86 // need to crack open bind_internal.h. On the other hand, it makes Bind()
87 // harder to read.
88
89 namespace base {
90
91 template <typename Functor>
92 base::Callback<typename cef_internal::BindState<
93 typename cef_internal::FunctorTraits<Functor>::RunnableType,
94 typename cef_internal::FunctorTraits<Functor>::RunType,
95 void()>::UnboundRunType>
Bind(Functor functor)96 Bind(Functor functor) {
97 // Typedefs for how to store and run the functor.
98 typedef
99 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
100 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
101
102 typedef cef_internal::BindState<RunnableType, RunType, void()> BindState;
103
104 return Callback<typename BindState::UnboundRunType>(
105 new BindState(cef_internal::MakeRunnable(functor)));
106 }
107
108 template <typename Functor, typename P1>
109 base::Callback<typename cef_internal::BindState<
110 typename cef_internal::FunctorTraits<Functor>::RunnableType,
111 typename cef_internal::FunctorTraits<Functor>::RunType,
112 void(typename cef_internal::CallbackParamTraits<P1>::StorageType)>::
113 UnboundRunType>
Bind(Functor functor,const P1 & p1)114 Bind(Functor functor, const P1& p1) {
115 // Typedefs for how to store and run the functor.
116 typedef
117 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
118 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
119
120 // Use RunnableType::RunType instead of RunType above because our
121 // checks should below for bound references need to know what the actual
122 // functor is going to interpret the argument as.
123 typedef cef_internal::FunctionTraits<typename RunnableType::RunType>
124 BoundFunctorTraits;
125
126 // Do not allow binding a non-const reference parameter. Non-const reference
127 // parameters are disallowed by the Google style guide. Also, binding a
128 // non-const reference parameter can make for subtle bugs because the
129 // invoked function will receive a reference to the stored copy of the
130 // argument and not the original.
131 COMPILE_ASSERT(
132 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value),
133 do_not_bind_functions_with_nonconst_ref);
134
135 // For methods, we need to be careful for parameter 1. We do not require
136 // a scoped_refptr because BindState<> itself takes care of AddRef() for
137 // methods. We also disallow binding of an array as the method's target
138 // object.
139 COMPILE_ASSERT(cef_internal::HasIsMethodTag<RunnableType>::value ||
140 !cef_internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
141 p1_is_refcounted_type_and_needs_scoped_refptr);
142 COMPILE_ASSERT(!cef_internal::HasIsMethodTag<RunnableType>::value ||
143 !is_array<P1>::value,
144 first_bound_argument_to_method_cannot_be_array);
145 typedef cef_internal::BindState<
146 RunnableType, RunType,
147 void(typename cef_internal::CallbackParamTraits<P1>::StorageType)>
148 BindState;
149
150 return Callback<typename BindState::UnboundRunType>(
151 new BindState(cef_internal::MakeRunnable(functor), p1));
152 }
153
154 template <typename Functor, typename P1, typename P2>
155 base::Callback<typename cef_internal::BindState<
156 typename cef_internal::FunctorTraits<Functor>::RunnableType,
157 typename cef_internal::FunctorTraits<Functor>::RunType,
158 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
159 typename cef_internal::CallbackParamTraits<P2>::StorageType)>::
160 UnboundRunType>
Bind(Functor functor,const P1 & p1,const P2 & p2)161 Bind(Functor functor, const P1& p1, const P2& p2) {
162 // Typedefs for how to store and run the functor.
163 typedef
164 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
165 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
166
167 // Use RunnableType::RunType instead of RunType above because our
168 // checks should below for bound references need to know what the actual
169 // functor is going to interpret the argument as.
170 typedef cef_internal::FunctionTraits<typename RunnableType::RunType>
171 BoundFunctorTraits;
172
173 // Do not allow binding a non-const reference parameter. Non-const reference
174 // parameters are disallowed by the Google style guide. Also, binding a
175 // non-const reference parameter can make for subtle bugs because the
176 // invoked function will receive a reference to the stored copy of the
177 // argument and not the original.
178 COMPILE_ASSERT(
179 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
180 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value),
181 do_not_bind_functions_with_nonconst_ref);
182
183 // For methods, we need to be careful for parameter 1. We do not require
184 // a scoped_refptr because BindState<> itself takes care of AddRef() for
185 // methods. We also disallow binding of an array as the method's target
186 // object.
187 COMPILE_ASSERT(cef_internal::HasIsMethodTag<RunnableType>::value ||
188 !cef_internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
189 p1_is_refcounted_type_and_needs_scoped_refptr);
190 COMPILE_ASSERT(!cef_internal::HasIsMethodTag<RunnableType>::value ||
191 !is_array<P1>::value,
192 first_bound_argument_to_method_cannot_be_array);
193 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
194 p2_is_refcounted_type_and_needs_scoped_refptr);
195 typedef cef_internal::BindState<
196 RunnableType, RunType,
197 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
198 typename cef_internal::CallbackParamTraits<P2>::StorageType)>
199 BindState;
200
201 return Callback<typename BindState::UnboundRunType>(
202 new BindState(cef_internal::MakeRunnable(functor), p1, p2));
203 }
204
205 template <typename Functor, typename P1, typename P2, typename P3>
206 base::Callback<typename cef_internal::BindState<
207 typename cef_internal::FunctorTraits<Functor>::RunnableType,
208 typename cef_internal::FunctorTraits<Functor>::RunType,
209 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
210 typename cef_internal::CallbackParamTraits<P2>::StorageType,
211 typename cef_internal::CallbackParamTraits<P3>::StorageType)>::
212 UnboundRunType>
Bind(Functor functor,const P1 & p1,const P2 & p2,const P3 & p3)213 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) {
214 // Typedefs for how to store and run the functor.
215 typedef
216 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
217 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
218
219 // Use RunnableType::RunType instead of RunType above because our
220 // checks should below for bound references need to know what the actual
221 // functor is going to interpret the argument as.
222 typedef cef_internal::FunctionTraits<typename RunnableType::RunType>
223 BoundFunctorTraits;
224
225 // Do not allow binding a non-const reference parameter. Non-const reference
226 // parameters are disallowed by the Google style guide. Also, binding a
227 // non-const reference parameter can make for subtle bugs because the
228 // invoked function will receive a reference to the stored copy of the
229 // argument and not the original.
230 COMPILE_ASSERT(
231 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
232 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
233 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value),
234 do_not_bind_functions_with_nonconst_ref);
235
236 // For methods, we need to be careful for parameter 1. We do not require
237 // a scoped_refptr because BindState<> itself takes care of AddRef() for
238 // methods. We also disallow binding of an array as the method's target
239 // object.
240 COMPILE_ASSERT(cef_internal::HasIsMethodTag<RunnableType>::value ||
241 !cef_internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
242 p1_is_refcounted_type_and_needs_scoped_refptr);
243 COMPILE_ASSERT(!cef_internal::HasIsMethodTag<RunnableType>::value ||
244 !is_array<P1>::value,
245 first_bound_argument_to_method_cannot_be_array);
246 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
247 p2_is_refcounted_type_and_needs_scoped_refptr);
248 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
249 p3_is_refcounted_type_and_needs_scoped_refptr);
250 typedef cef_internal::BindState<
251 RunnableType, RunType,
252 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
253 typename cef_internal::CallbackParamTraits<P2>::StorageType,
254 typename cef_internal::CallbackParamTraits<P3>::StorageType)>
255 BindState;
256
257 return Callback<typename BindState::UnboundRunType>(
258 new BindState(cef_internal::MakeRunnable(functor), p1, p2, p3));
259 }
260
261 template <typename Functor, typename P1, typename P2, typename P3, typename P4>
262 base::Callback<typename cef_internal::BindState<
263 typename cef_internal::FunctorTraits<Functor>::RunnableType,
264 typename cef_internal::FunctorTraits<Functor>::RunType,
265 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
266 typename cef_internal::CallbackParamTraits<P2>::StorageType,
267 typename cef_internal::CallbackParamTraits<P3>::StorageType,
268 typename cef_internal::CallbackParamTraits<P4>::StorageType)>::
269 UnboundRunType>
Bind(Functor functor,const P1 & p1,const P2 & p2,const P3 & p3,const P4 & p4)270 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
271 // Typedefs for how to store and run the functor.
272 typedef
273 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
274 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
275
276 // Use RunnableType::RunType instead of RunType above because our
277 // checks should below for bound references need to know what the actual
278 // functor is going to interpret the argument as.
279 typedef cef_internal::FunctionTraits<typename RunnableType::RunType>
280 BoundFunctorTraits;
281
282 // Do not allow binding a non-const reference parameter. Non-const reference
283 // parameters are disallowed by the Google style guide. Also, binding a
284 // non-const reference parameter can make for subtle bugs because the
285 // invoked function will receive a reference to the stored copy of the
286 // argument and not the original.
287 COMPILE_ASSERT(
288 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
289 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
290 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
291 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value),
292 do_not_bind_functions_with_nonconst_ref);
293
294 // For methods, we need to be careful for parameter 1. We do not require
295 // a scoped_refptr because BindState<> itself takes care of AddRef() for
296 // methods. We also disallow binding of an array as the method's target
297 // object.
298 COMPILE_ASSERT(cef_internal::HasIsMethodTag<RunnableType>::value ||
299 !cef_internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
300 p1_is_refcounted_type_and_needs_scoped_refptr);
301 COMPILE_ASSERT(!cef_internal::HasIsMethodTag<RunnableType>::value ||
302 !is_array<P1>::value,
303 first_bound_argument_to_method_cannot_be_array);
304 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
305 p2_is_refcounted_type_and_needs_scoped_refptr);
306 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
307 p3_is_refcounted_type_and_needs_scoped_refptr);
308 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
309 p4_is_refcounted_type_and_needs_scoped_refptr);
310 typedef cef_internal::BindState<
311 RunnableType, RunType,
312 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
313 typename cef_internal::CallbackParamTraits<P2>::StorageType,
314 typename cef_internal::CallbackParamTraits<P3>::StorageType,
315 typename cef_internal::CallbackParamTraits<P4>::StorageType)>
316 BindState;
317
318 return Callback<typename BindState::UnboundRunType>(
319 new BindState(cef_internal::MakeRunnable(functor), p1, p2, p3, p4));
320 }
321
322 template <typename Functor,
323 typename P1,
324 typename P2,
325 typename P3,
326 typename P4,
327 typename P5>
328 base::Callback<typename cef_internal::BindState<
329 typename cef_internal::FunctorTraits<Functor>::RunnableType,
330 typename cef_internal::FunctorTraits<Functor>::RunType,
331 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
332 typename cef_internal::CallbackParamTraits<P2>::StorageType,
333 typename cef_internal::CallbackParamTraits<P3>::StorageType,
334 typename cef_internal::CallbackParamTraits<P4>::StorageType,
335 typename cef_internal::CallbackParamTraits<P5>::StorageType)>::
336 UnboundRunType>
Bind(Functor functor,const P1 & p1,const P2 & p2,const P3 & p3,const P4 & p4,const P5 & p5)337 Bind(Functor functor,
338 const P1& p1,
339 const P2& p2,
340 const P3& p3,
341 const P4& p4,
342 const P5& p5) {
343 // Typedefs for how to store and run the functor.
344 typedef
345 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
346 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
347
348 // Use RunnableType::RunType instead of RunType above because our
349 // checks should below for bound references need to know what the actual
350 // functor is going to interpret the argument as.
351 typedef cef_internal::FunctionTraits<typename RunnableType::RunType>
352 BoundFunctorTraits;
353
354 // Do not allow binding a non-const reference parameter. Non-const reference
355 // parameters are disallowed by the Google style guide. Also, binding a
356 // non-const reference parameter can make for subtle bugs because the
357 // invoked function will receive a reference to the stored copy of the
358 // argument and not the original.
359 COMPILE_ASSERT(
360 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
361 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
362 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
363 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
364 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value),
365 do_not_bind_functions_with_nonconst_ref);
366
367 // For methods, we need to be careful for parameter 1. We do not require
368 // a scoped_refptr because BindState<> itself takes care of AddRef() for
369 // methods. We also disallow binding of an array as the method's target
370 // object.
371 COMPILE_ASSERT(cef_internal::HasIsMethodTag<RunnableType>::value ||
372 !cef_internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
373 p1_is_refcounted_type_and_needs_scoped_refptr);
374 COMPILE_ASSERT(!cef_internal::HasIsMethodTag<RunnableType>::value ||
375 !is_array<P1>::value,
376 first_bound_argument_to_method_cannot_be_array);
377 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
378 p2_is_refcounted_type_and_needs_scoped_refptr);
379 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
380 p3_is_refcounted_type_and_needs_scoped_refptr);
381 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
382 p4_is_refcounted_type_and_needs_scoped_refptr);
383 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
384 p5_is_refcounted_type_and_needs_scoped_refptr);
385 typedef cef_internal::BindState<
386 RunnableType, RunType,
387 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
388 typename cef_internal::CallbackParamTraits<P2>::StorageType,
389 typename cef_internal::CallbackParamTraits<P3>::StorageType,
390 typename cef_internal::CallbackParamTraits<P4>::StorageType,
391 typename cef_internal::CallbackParamTraits<P5>::StorageType)>
392 BindState;
393
394 return Callback<typename BindState::UnboundRunType>(
395 new BindState(cef_internal::MakeRunnable(functor), p1, p2, p3, p4, p5));
396 }
397
398 template <typename Functor,
399 typename P1,
400 typename P2,
401 typename P3,
402 typename P4,
403 typename P5,
404 typename P6>
405 base::Callback<typename cef_internal::BindState<
406 typename cef_internal::FunctorTraits<Functor>::RunnableType,
407 typename cef_internal::FunctorTraits<Functor>::RunType,
408 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
409 typename cef_internal::CallbackParamTraits<P2>::StorageType,
410 typename cef_internal::CallbackParamTraits<P3>::StorageType,
411 typename cef_internal::CallbackParamTraits<P4>::StorageType,
412 typename cef_internal::CallbackParamTraits<P5>::StorageType,
413 typename cef_internal::CallbackParamTraits<P6>::StorageType)>::
414 UnboundRunType>
Bind(Functor functor,const P1 & p1,const P2 & p2,const P3 & p3,const P4 & p4,const P5 & p5,const P6 & p6)415 Bind(Functor functor,
416 const P1& p1,
417 const P2& p2,
418 const P3& p3,
419 const P4& p4,
420 const P5& p5,
421 const P6& p6) {
422 // Typedefs for how to store and run the functor.
423 typedef
424 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
425 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
426
427 // Use RunnableType::RunType instead of RunType above because our
428 // checks should below for bound references need to know what the actual
429 // functor is going to interpret the argument as.
430 typedef cef_internal::FunctionTraits<typename RunnableType::RunType>
431 BoundFunctorTraits;
432
433 // Do not allow binding a non-const reference parameter. Non-const reference
434 // parameters are disallowed by the Google style guide. Also, binding a
435 // non-const reference parameter can make for subtle bugs because the
436 // invoked function will receive a reference to the stored copy of the
437 // argument and not the original.
438 COMPILE_ASSERT(
439 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
440 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
441 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
442 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
443 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
444 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value),
445 do_not_bind_functions_with_nonconst_ref);
446
447 // For methods, we need to be careful for parameter 1. We do not require
448 // a scoped_refptr because BindState<> itself takes care of AddRef() for
449 // methods. We also disallow binding of an array as the method's target
450 // object.
451 COMPILE_ASSERT(cef_internal::HasIsMethodTag<RunnableType>::value ||
452 !cef_internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
453 p1_is_refcounted_type_and_needs_scoped_refptr);
454 COMPILE_ASSERT(!cef_internal::HasIsMethodTag<RunnableType>::value ||
455 !is_array<P1>::value,
456 first_bound_argument_to_method_cannot_be_array);
457 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
458 p2_is_refcounted_type_and_needs_scoped_refptr);
459 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
460 p3_is_refcounted_type_and_needs_scoped_refptr);
461 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
462 p4_is_refcounted_type_and_needs_scoped_refptr);
463 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
464 p5_is_refcounted_type_and_needs_scoped_refptr);
465 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
466 p6_is_refcounted_type_and_needs_scoped_refptr);
467 typedef cef_internal::BindState<
468 RunnableType, RunType,
469 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
470 typename cef_internal::CallbackParamTraits<P2>::StorageType,
471 typename cef_internal::CallbackParamTraits<P3>::StorageType,
472 typename cef_internal::CallbackParamTraits<P4>::StorageType,
473 typename cef_internal::CallbackParamTraits<P5>::StorageType,
474 typename cef_internal::CallbackParamTraits<P6>::StorageType)>
475 BindState;
476
477 return Callback<typename BindState::UnboundRunType>(new BindState(
478 cef_internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6));
479 }
480
481 template <typename Functor,
482 typename P1,
483 typename P2,
484 typename P3,
485 typename P4,
486 typename P5,
487 typename P6,
488 typename P7>
489 base::Callback<typename cef_internal::BindState<
490 typename cef_internal::FunctorTraits<Functor>::RunnableType,
491 typename cef_internal::FunctorTraits<Functor>::RunType,
492 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
493 typename cef_internal::CallbackParamTraits<P2>::StorageType,
494 typename cef_internal::CallbackParamTraits<P3>::StorageType,
495 typename cef_internal::CallbackParamTraits<P4>::StorageType,
496 typename cef_internal::CallbackParamTraits<P5>::StorageType,
497 typename cef_internal::CallbackParamTraits<P6>::StorageType,
498 typename cef_internal::CallbackParamTraits<P7>::StorageType)>::
499 UnboundRunType>
Bind(Functor functor,const P1 & p1,const P2 & p2,const P3 & p3,const P4 & p4,const P5 & p5,const P6 & p6,const P7 & p7)500 Bind(Functor functor,
501 const P1& p1,
502 const P2& p2,
503 const P3& p3,
504 const P4& p4,
505 const P5& p5,
506 const P6& p6,
507 const P7& p7) {
508 // Typedefs for how to store and run the functor.
509 typedef
510 typename cef_internal::FunctorTraits<Functor>::RunnableType RunnableType;
511 typedef typename cef_internal::FunctorTraits<Functor>::RunType RunType;
512
513 // Use RunnableType::RunType instead of RunType above because our
514 // checks should below for bound references need to know what the actual
515 // functor is going to interpret the argument as.
516 typedef cef_internal::FunctionTraits<typename RunnableType::RunType>
517 BoundFunctorTraits;
518
519 // Do not allow binding a non-const reference parameter. Non-const reference
520 // parameters are disallowed by the Google style guide. Also, binding a
521 // non-const reference parameter can make for subtle bugs because the
522 // invoked function will receive a reference to the stored copy of the
523 // argument and not the original.
524 COMPILE_ASSERT(
525 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
526 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
527 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
528 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
529 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
530 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ||
531 is_non_const_reference<typename BoundFunctorTraits::A7Type>::value),
532 do_not_bind_functions_with_nonconst_ref);
533
534 // For methods, we need to be careful for parameter 1. We do not require
535 // a scoped_refptr because BindState<> itself takes care of AddRef() for
536 // methods. We also disallow binding of an array as the method's target
537 // object.
538 COMPILE_ASSERT(cef_internal::HasIsMethodTag<RunnableType>::value ||
539 !cef_internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
540 p1_is_refcounted_type_and_needs_scoped_refptr);
541 COMPILE_ASSERT(!cef_internal::HasIsMethodTag<RunnableType>::value ||
542 !is_array<P1>::value,
543 first_bound_argument_to_method_cannot_be_array);
544 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
545 p2_is_refcounted_type_and_needs_scoped_refptr);
546 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
547 p3_is_refcounted_type_and_needs_scoped_refptr);
548 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
549 p4_is_refcounted_type_and_needs_scoped_refptr);
550 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
551 p5_is_refcounted_type_and_needs_scoped_refptr);
552 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
553 p6_is_refcounted_type_and_needs_scoped_refptr);
554 COMPILE_ASSERT(!cef_internal::NeedsScopedRefptrButGetsRawPtr<P7>::value,
555 p7_is_refcounted_type_and_needs_scoped_refptr);
556 typedef cef_internal::BindState<
557 RunnableType, RunType,
558 void(typename cef_internal::CallbackParamTraits<P1>::StorageType,
559 typename cef_internal::CallbackParamTraits<P2>::StorageType,
560 typename cef_internal::CallbackParamTraits<P3>::StorageType,
561 typename cef_internal::CallbackParamTraits<P4>::StorageType,
562 typename cef_internal::CallbackParamTraits<P5>::StorageType,
563 typename cef_internal::CallbackParamTraits<P6>::StorageType,
564 typename cef_internal::CallbackParamTraits<P7>::StorageType)>
565 BindState;
566
567 return Callback<typename BindState::UnboundRunType>(new BindState(
568 cef_internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6, p7));
569 }
570
571 } // namespace base
572
573 #endif // !USING_CHROMIUM_INCLUDES
574
575 #endif // CEF_INCLUDE_BASE_CEF_BIND_H_
576