OLD | NEW |
1 // This file was GENERATED by command: | 1 // This file was GENERATED by command: |
2 // pump.py bind.h.pump | 2 // pump.py bind.h.pump |
3 // DO NOT EDIT BY HAND!!! | 3 // DO NOT EDIT BY HAND!!! |
4 | 4 |
5 | 5 |
6 | 6 |
7 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 7 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
8 // Use of this source code is governed by a BSD-style license that can be | 8 // Use of this source code is governed by a BSD-style license that can be |
9 // found in the LICENSE file. | 9 // found in the LICENSE file. |
10 | 10 |
11 #ifndef BASE_BIND_H_ | 11 #ifndef BASE_BIND_H_ |
12 #define BASE_BIND_H_ | 12 #define BASE_BIND_H_ |
13 #pragma once | 13 #pragma once |
14 | 14 |
15 #include "base/bind_internal.h" | 15 #include "base/bind_internal.h" |
16 #include "base/callback_internal.h" | 16 #include "base/callback_internal.h" |
17 | 17 |
18 // See base/callback.h for how to use these functions. | 18 // See base/callback.h for how to use these functions. If reading the |
| 19 // implementation, before proceeding further, you should read the top |
| 20 // comment of base/bind_internal.h for a definition of common terms and |
| 21 // concepts. |
19 // | 22 // |
20 // IMPLEMENTATION NOTE | 23 // IMPLEMENTATION NOTE |
21 // Though Bind()'s result is meant to be stored in a Callback<> type, it | 24 // Though Bind()'s result is meant to be stored in a Callback<> type, it |
22 // cannot actually return the exact type without requiring a large amount | 25 // cannot actually return the exact type without requiring a large amount |
23 // of extra template specializations. The problem is that in order to | 26 // of extra template specializations. The problem is that in order to |
24 // discern the correct specialization of Callback<>, Bind would need to | 27 // discern the correct specialization of Callback<>, Bind would need to |
25 // unwrap the function signature to determine the signature's arity, and | 28 // unwrap the function signature to determine the signature's arity, and |
26 // whether or not it is a method. | 29 // whether or not it is a method. |
27 // | 30 // |
28 // Each unique combination of (arity, function_type, num_prebound) where | 31 // Each unique combination of (arity, function_type, num_prebound) where |
29 // function_type is one of {function, method, const_method} would require | 32 // function_type is one of {function, method, const_method} would require |
30 // one specialization. We eventually have to do a similar number of | 33 // one specialization. We eventually have to do a similar number of |
31 // specializations anyways in the implementation (see the FunctionTraitsN, | 34 // specializations anyways in the implementation (see the Invoker<>, |
32 // classes). However, it is avoidable in Bind if we return the result | 35 // classes). However, it is avoidable in Bind if we return the result |
33 // via an indirection like we do below. | 36 // via an indirection like we do below. |
| 37 // |
| 38 // TODO(ajwong): We might be able to avoid this now, but need to test. |
| 39 // |
| 40 // It is possible to move most of the COMPILE_ASSERT asserts into BindState<>, |
| 41 // but it feels a little nicer to have the asserts here so people do not |
| 42 // need to crack open bind_internal.h. On the other hand, it makes Bind() |
| 43 // harder to read. |
34 | 44 |
35 namespace base { | 45 namespace base { |
36 | 46 |
37 template <typename Sig> | 47 template <typename Functor> |
38 internal::InvokerStorageHolder<internal::InvokerStorage0<Sig> > | 48 internal::BindStateHolder< |
39 Bind(Sig f) { | 49 internal::BindState< |
40 return internal::MakeInvokerStorageHolder( | 50 typename internal::FunctorTraits<Functor>::RunnableType, |
41 new internal::InvokerStorage0<Sig>(f)); | 51 typename internal::FunctorTraits<Functor>::RunType, |
42 } | 52 void()> > |
43 | 53 Bind(Functor functor) { |
44 template <typename Sig, typename P1> | 54 // Typedefs for how to store and run the functor. |
45 internal::InvokerStorageHolder<internal::InvokerStorage1<Sig,P1> > | 55 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
46 Bind(Sig f, const P1& p1) { | 56 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
47 return internal::MakeInvokerStorageHolder( | 57 |
48 new internal::InvokerStorage1<Sig, P1>( | 58 // Use RunnableType::RunType instead of RunType above because our |
49 f, p1)); | 59 // checks should below for bound references need to know what the actual |
50 } | 60 // functor is going to interpret the argument as. |
51 | 61 typedef internal::FunctionTraits<typename RunnableType::RunType> |
52 template <typename Sig, typename P1, typename P2> | 62 BoundFunctorTraits; |
53 internal::InvokerStorageHolder<internal::InvokerStorage2<Sig,P1, P2> > | 63 |
54 Bind(Sig f, const P1& p1, const P2& p2) { | 64 |
55 return internal::MakeInvokerStorageHolder( | 65 return internal::MakeBindStateHolder( |
56 new internal::InvokerStorage2<Sig, P1, P2>( | 66 new internal::BindState<RunnableType, RunType, void()>( |
57 f, p1, p2)); | 67 internal::MakeRunnable(functor))); |
58 } | 68 } |
59 | 69 |
60 template <typename Sig, typename P1, typename P2, typename P3> | 70 template <typename Functor, typename P1> |
61 internal::InvokerStorageHolder<internal::InvokerStorage3<Sig,P1, P2, P3> > | 71 internal::BindStateHolder< |
62 Bind(Sig f, const P1& p1, const P2& p2, const P3& p3) { | 72 internal::BindState< |
63 return internal::MakeInvokerStorageHolder( | 73 typename internal::FunctorTraits<Functor>::RunnableType, |
64 new internal::InvokerStorage3<Sig, P1, P2, P3>( | 74 typename internal::FunctorTraits<Functor>::RunType, |
65 f, p1, p2, p3)); | 75 void(typename internal::CallbackParamTraits<P1>::StorageType)> > |
66 } | 76 Bind(Functor functor, const P1& p1) { |
67 | 77 // Typedefs for how to store and run the functor. |
68 template <typename Sig, typename P1, typename P2, typename P3, typename P4> | 78 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
69 internal::InvokerStorageHolder<internal::InvokerStorage4<Sig,P1, P2, P3, P4> > | 79 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
70 Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4) { | 80 |
71 return internal::MakeInvokerStorageHolder( | 81 // Use RunnableType::RunType instead of RunType above because our |
72 new internal::InvokerStorage4<Sig, P1, P2, P3, P4>( | 82 // checks should below for bound references need to know what the actual |
73 f, p1, p2, p3, p4)); | 83 // functor is going to interpret the argument as. |
74 } | 84 typedef internal::FunctionTraits<typename RunnableType::RunType> |
75 | 85 BoundFunctorTraits; |
76 template <typename Sig, typename P1, typename P2, typename P3, typename P4, | 86 |
| 87 // Do not allow binding a non-const reference parameter. Non-const reference |
| 88 // parameters are disallowed by the Google style guide. Also, binding a |
| 89 // non-const reference parameter can make for subtle bugs because the |
| 90 // invoked function will receive a reference to the stored copy of the |
| 91 // argument and not the original. |
| 92 COMPILE_ASSERT( |
| 93 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ), |
| 94 do_not_bind_functions_with_nonconst_ref); |
| 95 |
| 96 // For methods, we need to be careful for parameter 1. We skip the |
| 97 // scoped_refptr check because the binder itself takes care of this. We also |
| 98 // disallow binding of an array as the method's target object. |
| 99 COMPILE_ASSERT( |
| 100 internal::HasIsMethodTag<RunnableType>::value || |
| 101 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 102 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 103 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 104 !is_array<P1>::value, |
| 105 first_bound_argument_to_method_cannot_be_array); |
| 106 |
| 107 return internal::MakeBindStateHolder( |
| 108 new internal::BindState<RunnableType, RunType, |
| 109 void(typename internal::CallbackParamTraits<P1>::StorageType)>( |
| 110 internal::MakeRunnable(functor), p1)); |
| 111 } |
| 112 |
| 113 template <typename Functor, typename P1, typename P2> |
| 114 internal::BindStateHolder< |
| 115 internal::BindState< |
| 116 typename internal::FunctorTraits<Functor>::RunnableType, |
| 117 typename internal::FunctorTraits<Functor>::RunType, |
| 118 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 119 typename internal::CallbackParamTraits<P2>::StorageType)> > |
| 120 Bind(Functor functor, const P1& p1, const P2& p2) { |
| 121 // Typedefs for how to store and run the functor. |
| 122 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
| 123 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
| 124 |
| 125 // Use RunnableType::RunType instead of RunType above because our |
| 126 // checks should below for bound references need to know what the actual |
| 127 // functor is going to interpret the argument as. |
| 128 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 129 BoundFunctorTraits; |
| 130 |
| 131 // Do not allow binding a non-const reference parameter. Non-const reference |
| 132 // parameters are disallowed by the Google style guide. Also, binding a |
| 133 // non-const reference parameter can make for subtle bugs because the |
| 134 // invoked function will receive a reference to the stored copy of the |
| 135 // argument and not the original. |
| 136 COMPILE_ASSERT( |
| 137 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 138 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ), |
| 139 do_not_bind_functions_with_nonconst_ref); |
| 140 |
| 141 // For methods, we need to be careful for parameter 1. We skip the |
| 142 // scoped_refptr check because the binder itself takes care of this. We also |
| 143 // disallow binding of an array as the method's target object. |
| 144 COMPILE_ASSERT( |
| 145 internal::HasIsMethodTag<RunnableType>::value || |
| 146 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 147 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 148 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 149 !is_array<P1>::value, |
| 150 first_bound_argument_to_method_cannot_be_array); |
| 151 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 152 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 153 |
| 154 return internal::MakeBindStateHolder( |
| 155 new internal::BindState<RunnableType, RunType, |
| 156 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 157 typename internal::CallbackParamTraits<P2>::StorageType)>( |
| 158 internal::MakeRunnable(functor), p1, p2)); |
| 159 } |
| 160 |
| 161 template <typename Functor, typename P1, typename P2, typename P3> |
| 162 internal::BindStateHolder< |
| 163 internal::BindState< |
| 164 typename internal::FunctorTraits<Functor>::RunnableType, |
| 165 typename internal::FunctorTraits<Functor>::RunType, |
| 166 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 167 typename internal::CallbackParamTraits<P2>::StorageType, |
| 168 typename internal::CallbackParamTraits<P3>::StorageType)> > |
| 169 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) { |
| 170 // Typedefs for how to store and run the functor. |
| 171 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
| 172 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
| 173 |
| 174 // Use RunnableType::RunType instead of RunType above because our |
| 175 // checks should below for bound references need to know what the actual |
| 176 // functor is going to interpret the argument as. |
| 177 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 178 BoundFunctorTraits; |
| 179 |
| 180 // Do not allow binding a non-const reference parameter. Non-const reference |
| 181 // parameters are disallowed by the Google style guide. Also, binding a |
| 182 // non-const reference parameter can make for subtle bugs because the |
| 183 // invoked function will receive a reference to the stored copy of the |
| 184 // argument and not the original. |
| 185 COMPILE_ASSERT( |
| 186 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 187 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
| 188 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ), |
| 189 do_not_bind_functions_with_nonconst_ref); |
| 190 |
| 191 // For methods, we need to be careful for parameter 1. We skip the |
| 192 // scoped_refptr check because the binder itself takes care of this. We also |
| 193 // disallow binding of an array as the method's target object. |
| 194 COMPILE_ASSERT( |
| 195 internal::HasIsMethodTag<RunnableType>::value || |
| 196 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 197 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 198 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 199 !is_array<P1>::value, |
| 200 first_bound_argument_to_method_cannot_be_array); |
| 201 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 202 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 203 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
| 204 p3_is_refcounted_type_and_needs_scoped_refptr); |
| 205 |
| 206 return internal::MakeBindStateHolder( |
| 207 new internal::BindState<RunnableType, RunType, |
| 208 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 209 typename internal::CallbackParamTraits<P2>::StorageType, |
| 210 typename internal::CallbackParamTraits<P3>::StorageType)>( |
| 211 internal::MakeRunnable(functor), p1, p2, p3)); |
| 212 } |
| 213 |
| 214 template <typename Functor, typename P1, typename P2, typename P3, typename P4> |
| 215 internal::BindStateHolder< |
| 216 internal::BindState< |
| 217 typename internal::FunctorTraits<Functor>::RunnableType, |
| 218 typename internal::FunctorTraits<Functor>::RunType, |
| 219 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 220 typename internal::CallbackParamTraits<P2>::StorageType, |
| 221 typename internal::CallbackParamTraits<P3>::StorageType, |
| 222 typename internal::CallbackParamTraits<P4>::StorageType)> > |
| 223 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) { |
| 224 // Typedefs for how to store and run the functor. |
| 225 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
| 226 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
| 227 |
| 228 // Use RunnableType::RunType instead of RunType above because our |
| 229 // checks should below for bound references need to know what the actual |
| 230 // functor is going to interpret the argument as. |
| 231 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 232 BoundFunctorTraits; |
| 233 |
| 234 // Do not allow binding a non-const reference parameter. Non-const reference |
| 235 // parameters are disallowed by the Google style guide. Also, binding a |
| 236 // non-const reference parameter can make for subtle bugs because the |
| 237 // invoked function will receive a reference to the stored copy of the |
| 238 // argument and not the original. |
| 239 COMPILE_ASSERT( |
| 240 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 241 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
| 242 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value || |
| 243 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ), |
| 244 do_not_bind_functions_with_nonconst_ref); |
| 245 |
| 246 // For methods, we need to be careful for parameter 1. We skip the |
| 247 // scoped_refptr check because the binder itself takes care of this. We also |
| 248 // disallow binding of an array as the method's target object. |
| 249 COMPILE_ASSERT( |
| 250 internal::HasIsMethodTag<RunnableType>::value || |
| 251 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 252 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 253 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 254 !is_array<P1>::value, |
| 255 first_bound_argument_to_method_cannot_be_array); |
| 256 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 257 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 258 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
| 259 p3_is_refcounted_type_and_needs_scoped_refptr); |
| 260 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value, |
| 261 p4_is_refcounted_type_and_needs_scoped_refptr); |
| 262 |
| 263 return internal::MakeBindStateHolder( |
| 264 new internal::BindState<RunnableType, RunType, |
| 265 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 266 typename internal::CallbackParamTraits<P2>::StorageType, |
| 267 typename internal::CallbackParamTraits<P3>::StorageType, |
| 268 typename internal::CallbackParamTraits<P4>::StorageType)>( |
| 269 internal::MakeRunnable(functor), p1, p2, p3, p4)); |
| 270 } |
| 271 |
| 272 template <typename Functor, typename P1, typename P2, typename P3, typename P4, |
77 typename P5> | 273 typename P5> |
78 internal::InvokerStorageHolder<internal::InvokerStorage5<Sig,P1, P2, P3, P4, | 274 internal::BindStateHolder< |
79 P5> > | 275 internal::BindState< |
80 Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4, | 276 typename internal::FunctorTraits<Functor>::RunnableType, |
| 277 typename internal::FunctorTraits<Functor>::RunType, |
| 278 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 279 typename internal::CallbackParamTraits<P2>::StorageType, |
| 280 typename internal::CallbackParamTraits<P3>::StorageType, |
| 281 typename internal::CallbackParamTraits<P4>::StorageType, |
| 282 typename internal::CallbackParamTraits<P5>::StorageType)> > |
| 283 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4, |
81 const P5& p5) { | 284 const P5& p5) { |
82 return internal::MakeInvokerStorageHolder( | 285 // Typedefs for how to store and run the functor. |
83 new internal::InvokerStorage5<Sig, P1, P2, P3, P4, P5>( | 286 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
84 f, p1, p2, p3, p4, p5)); | 287 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
85 } | 288 |
86 | 289 // Use RunnableType::RunType instead of RunType above because our |
87 template <typename Sig, typename P1, typename P2, typename P3, typename P4, | 290 // checks should below for bound references need to know what the actual |
| 291 // functor is going to interpret the argument as. |
| 292 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 293 BoundFunctorTraits; |
| 294 |
| 295 // Do not allow binding a non-const reference parameter. Non-const reference |
| 296 // parameters are disallowed by the Google style guide. Also, binding a |
| 297 // non-const reference parameter can make for subtle bugs because the |
| 298 // invoked function will receive a reference to the stored copy of the |
| 299 // argument and not the original. |
| 300 COMPILE_ASSERT( |
| 301 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 302 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
| 303 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value || |
| 304 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value || |
| 305 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ), |
| 306 do_not_bind_functions_with_nonconst_ref); |
| 307 |
| 308 // For methods, we need to be careful for parameter 1. We skip the |
| 309 // scoped_refptr check because the binder itself takes care of this. We also |
| 310 // disallow binding of an array as the method's target object. |
| 311 COMPILE_ASSERT( |
| 312 internal::HasIsMethodTag<RunnableType>::value || |
| 313 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 314 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 315 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 316 !is_array<P1>::value, |
| 317 first_bound_argument_to_method_cannot_be_array); |
| 318 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 319 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 320 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
| 321 p3_is_refcounted_type_and_needs_scoped_refptr); |
| 322 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value, |
| 323 p4_is_refcounted_type_and_needs_scoped_refptr); |
| 324 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value, |
| 325 p5_is_refcounted_type_and_needs_scoped_refptr); |
| 326 |
| 327 return internal::MakeBindStateHolder( |
| 328 new internal::BindState<RunnableType, RunType, |
| 329 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 330 typename internal::CallbackParamTraits<P2>::StorageType, |
| 331 typename internal::CallbackParamTraits<P3>::StorageType, |
| 332 typename internal::CallbackParamTraits<P4>::StorageType, |
| 333 typename internal::CallbackParamTraits<P5>::StorageType)>( |
| 334 internal::MakeRunnable(functor), p1, p2, p3, p4, p5)); |
| 335 } |
| 336 |
| 337 template <typename Functor, typename P1, typename P2, typename P3, typename P4, |
88 typename P5, typename P6> | 338 typename P5, typename P6> |
89 internal::InvokerStorageHolder<internal::InvokerStorage6<Sig,P1, P2, P3, P4, | 339 internal::BindStateHolder< |
90 P5, P6> > | 340 internal::BindState< |
91 Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4, | 341 typename internal::FunctorTraits<Functor>::RunnableType, |
| 342 typename internal::FunctorTraits<Functor>::RunType, |
| 343 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 344 typename internal::CallbackParamTraits<P2>::StorageType, |
| 345 typename internal::CallbackParamTraits<P3>::StorageType, |
| 346 typename internal::CallbackParamTraits<P4>::StorageType, |
| 347 typename internal::CallbackParamTraits<P5>::StorageType, |
| 348 typename internal::CallbackParamTraits<P6>::StorageType)> > |
| 349 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4, |
92 const P5& p5, const P6& p6) { | 350 const P5& p5, const P6& p6) { |
93 return internal::MakeInvokerStorageHolder( | 351 // Typedefs for how to store and run the functor. |
94 new internal::InvokerStorage6<Sig, P1, P2, P3, P4, P5, P6>( | 352 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
95 f, p1, p2, p3, p4, p5, p6)); | 353 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
96 } | 354 |
97 | 355 // Use RunnableType::RunType instead of RunType above because our |
98 // Specializations to allow binding all the free arguments in a | 356 // checks should below for bound references need to know what the actual |
99 // pre-existing base::Callback<>. This does not give full support for | 357 // functor is going to interpret the argument as. |
100 // currying, but is significantly simpler and addresses the use case | 358 typedef internal::FunctionTraits<typename RunnableType::RunType> |
101 // where a base::Callback<> needs to be invoked on another context/thread. | 359 BoundFunctorTraits; |
102 template <typename Sig, typename P1> | 360 |
103 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1) { | 361 // Do not allow binding a non-const reference parameter. Non-const reference |
104 return base::Bind(&internal::BindMoreFunc1<Sig, P1>, callback, p1); | 362 // parameters are disallowed by the Google style guide. Also, binding a |
105 } | 363 // non-const reference parameter can make for subtle bugs because the |
106 | 364 // invoked function will receive a reference to the stored copy of the |
107 template <typename Sig, typename P1, typename P2> | 365 // argument and not the original. |
108 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 366 COMPILE_ASSERT( |
109 const P2& p2) { | 367 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
110 return base::Bind(&internal::BindMoreFunc2<Sig, P1, P2>, callback, p1, p2); | 368 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
111 } | 369 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value || |
112 | 370 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value || |
113 template <typename Sig, typename P1, typename P2, typename P3> | 371 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value || |
114 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 372 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ), |
115 const P2& p2, const P3& p3) { | 373 do_not_bind_functions_with_nonconst_ref); |
116 return base::Bind(&internal::BindMoreFunc3<Sig, P1, P2, P3>, callback, p1, | 374 |
117 p2, p3); | 375 // For methods, we need to be careful for parameter 1. We skip the |
118 } | 376 // scoped_refptr check because the binder itself takes care of this. We also |
119 | 377 // disallow binding of an array as the method's target object. |
120 template <typename Sig, typename P1, typename P2, typename P3, typename P4> | 378 COMPILE_ASSERT( |
121 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 379 internal::HasIsMethodTag<RunnableType>::value || |
122 const P2& p2, const P3& p3, const P4& p4) { | 380 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
123 return base::Bind(&internal::BindMoreFunc4<Sig, P1, P2, P3, P4>, callback, | 381 p1_is_refcounted_type_and_needs_scoped_refptr); |
124 p1, p2, p3, p4); | 382 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
125 } | 383 !is_array<P1>::value, |
126 | 384 first_bound_argument_to_method_cannot_be_array); |
127 template <typename Sig, typename P1, typename P2, typename P3, typename P4, | 385 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
128 typename P5> | 386 p2_is_refcounted_type_and_needs_scoped_refptr); |
129 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 387 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
130 const P2& p2, const P3& p3, const P4& p4, const P5& p5) { | 388 p3_is_refcounted_type_and_needs_scoped_refptr); |
131 return base::Bind(&internal::BindMoreFunc5<Sig, P1, P2, P3, P4, P5>, | 389 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value, |
132 callback, p1, p2, p3, p4, p5); | 390 p4_is_refcounted_type_and_needs_scoped_refptr); |
133 } | 391 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value, |
134 | 392 p5_is_refcounted_type_and_needs_scoped_refptr); |
135 template <typename Sig, typename P1, typename P2, typename P3, typename P4, | 393 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value, |
136 typename P5, typename P6> | 394 p6_is_refcounted_type_and_needs_scoped_refptr); |
137 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 395 |
138 const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) { | 396 return internal::MakeBindStateHolder( |
139 return base::Bind(&internal::BindMoreFunc6<Sig, P1, P2, P3, P4, P5, P6>, | 397 new internal::BindState<RunnableType, RunType, |
140 callback, p1, p2, p3, p4, p5, p6); | 398 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 399 typename internal::CallbackParamTraits<P2>::StorageType, |
| 400 typename internal::CallbackParamTraits<P3>::StorageType, |
| 401 typename internal::CallbackParamTraits<P4>::StorageType, |
| 402 typename internal::CallbackParamTraits<P5>::StorageType, |
| 403 typename internal::CallbackParamTraits<P6>::StorageType)>( |
| 404 internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6)); |
141 } | 405 } |
142 | 406 |
143 } // namespace base | 407 } // namespace base |
144 | 408 |
145 #endif // BASE_BIND_H_ | 409 #endif // BASE_BIND_H_ |
OLD | NEW |