• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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