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 do not require |
| 97 // a scoped_refptr because BindState<> itself takes care of AddRef() for |
| 98 // methods. We also disallow binding of an array as the method's target |
| 99 // object. |
| 100 COMPILE_ASSERT( |
| 101 internal::HasIsMethodTag<RunnableType>::value || |
| 102 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 103 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 104 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 105 !is_array<P1>::value, |
| 106 first_bound_argument_to_method_cannot_be_array); |
| 107 |
| 108 return internal::MakeBindStateHolder( |
| 109 new internal::BindState<RunnableType, RunType, |
| 110 void(typename internal::CallbackParamTraits<P1>::StorageType)>( |
| 111 internal::MakeRunnable(functor), p1)); |
| 112 } |
| 113 |
| 114 template <typename Functor, typename P1, typename P2> |
| 115 internal::BindStateHolder< |
| 116 internal::BindState< |
| 117 typename internal::FunctorTraits<Functor>::RunnableType, |
| 118 typename internal::FunctorTraits<Functor>::RunType, |
| 119 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 120 typename internal::CallbackParamTraits<P2>::StorageType)> > |
| 121 Bind(Functor functor, const P1& p1, const P2& p2) { |
| 122 // Typedefs for how to store and run the functor. |
| 123 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
| 124 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
| 125 |
| 126 // Use RunnableType::RunType instead of RunType above because our |
| 127 // checks should below for bound references need to know what the actual |
| 128 // functor is going to interpret the argument as. |
| 129 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 130 BoundFunctorTraits; |
| 131 |
| 132 // Do not allow binding a non-const reference parameter. Non-const reference |
| 133 // parameters are disallowed by the Google style guide. Also, binding a |
| 134 // non-const reference parameter can make for subtle bugs because the |
| 135 // invoked function will receive a reference to the stored copy of the |
| 136 // argument and not the original. |
| 137 COMPILE_ASSERT( |
| 138 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 139 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ), |
| 140 do_not_bind_functions_with_nonconst_ref); |
| 141 |
| 142 // For methods, we need to be careful for parameter 1. We do not require |
| 143 // a scoped_refptr because BindState<> itself takes care of AddRef() for |
| 144 // methods. We also disallow binding of an array as the method's target |
| 145 // object. |
| 146 COMPILE_ASSERT( |
| 147 internal::HasIsMethodTag<RunnableType>::value || |
| 148 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 149 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 150 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 151 !is_array<P1>::value, |
| 152 first_bound_argument_to_method_cannot_be_array); |
| 153 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 154 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 155 |
| 156 return internal::MakeBindStateHolder( |
| 157 new internal::BindState<RunnableType, RunType, |
| 158 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 159 typename internal::CallbackParamTraits<P2>::StorageType)>( |
| 160 internal::MakeRunnable(functor), p1, p2)); |
| 161 } |
| 162 |
| 163 template <typename Functor, typename P1, typename P2, typename P3> |
| 164 internal::BindStateHolder< |
| 165 internal::BindState< |
| 166 typename internal::FunctorTraits<Functor>::RunnableType, |
| 167 typename internal::FunctorTraits<Functor>::RunType, |
| 168 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 169 typename internal::CallbackParamTraits<P2>::StorageType, |
| 170 typename internal::CallbackParamTraits<P3>::StorageType)> > |
| 171 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) { |
| 172 // Typedefs for how to store and run the functor. |
| 173 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
| 174 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
| 175 |
| 176 // Use RunnableType::RunType instead of RunType above because our |
| 177 // checks should below for bound references need to know what the actual |
| 178 // functor is going to interpret the argument as. |
| 179 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 180 BoundFunctorTraits; |
| 181 |
| 182 // Do not allow binding a non-const reference parameter. Non-const reference |
| 183 // parameters are disallowed by the Google style guide. Also, binding a |
| 184 // non-const reference parameter can make for subtle bugs because the |
| 185 // invoked function will receive a reference to the stored copy of the |
| 186 // argument and not the original. |
| 187 COMPILE_ASSERT( |
| 188 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 189 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
| 190 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ), |
| 191 do_not_bind_functions_with_nonconst_ref); |
| 192 |
| 193 // For methods, we need to be careful for parameter 1. We do not require |
| 194 // a scoped_refptr because BindState<> itself takes care of AddRef() for |
| 195 // methods. We also disallow binding of an array as the method's target |
| 196 // object. |
| 197 COMPILE_ASSERT( |
| 198 internal::HasIsMethodTag<RunnableType>::value || |
| 199 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 200 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 201 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 202 !is_array<P1>::value, |
| 203 first_bound_argument_to_method_cannot_be_array); |
| 204 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 205 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 206 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
| 207 p3_is_refcounted_type_and_needs_scoped_refptr); |
| 208 |
| 209 return internal::MakeBindStateHolder( |
| 210 new internal::BindState<RunnableType, RunType, |
| 211 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 212 typename internal::CallbackParamTraits<P2>::StorageType, |
| 213 typename internal::CallbackParamTraits<P3>::StorageType)>( |
| 214 internal::MakeRunnable(functor), p1, p2, p3)); |
| 215 } |
| 216 |
| 217 template <typename Functor, typename P1, typename P2, typename P3, typename P4> |
| 218 internal::BindStateHolder< |
| 219 internal::BindState< |
| 220 typename internal::FunctorTraits<Functor>::RunnableType, |
| 221 typename internal::FunctorTraits<Functor>::RunType, |
| 222 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 223 typename internal::CallbackParamTraits<P2>::StorageType, |
| 224 typename internal::CallbackParamTraits<P3>::StorageType, |
| 225 typename internal::CallbackParamTraits<P4>::StorageType)> > |
| 226 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) { |
| 227 // Typedefs for how to store and run the functor. |
| 228 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
| 229 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
| 230 |
| 231 // Use RunnableType::RunType instead of RunType above because our |
| 232 // checks should below for bound references need to know what the actual |
| 233 // functor is going to interpret the argument as. |
| 234 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 235 BoundFunctorTraits; |
| 236 |
| 237 // Do not allow binding a non-const reference parameter. Non-const reference |
| 238 // parameters are disallowed by the Google style guide. Also, binding a |
| 239 // non-const reference parameter can make for subtle bugs because the |
| 240 // invoked function will receive a reference to the stored copy of the |
| 241 // argument and not the original. |
| 242 COMPILE_ASSERT( |
| 243 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 244 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
| 245 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value || |
| 246 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ), |
| 247 do_not_bind_functions_with_nonconst_ref); |
| 248 |
| 249 // For methods, we need to be careful for parameter 1. We do not require |
| 250 // a scoped_refptr because BindState<> itself takes care of AddRef() for |
| 251 // methods. We also disallow binding of an array as the method's target |
| 252 // object. |
| 253 COMPILE_ASSERT( |
| 254 internal::HasIsMethodTag<RunnableType>::value || |
| 255 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 256 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 257 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 258 !is_array<P1>::value, |
| 259 first_bound_argument_to_method_cannot_be_array); |
| 260 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 261 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 262 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
| 263 p3_is_refcounted_type_and_needs_scoped_refptr); |
| 264 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value, |
| 265 p4_is_refcounted_type_and_needs_scoped_refptr); |
| 266 |
| 267 return internal::MakeBindStateHolder( |
| 268 new internal::BindState<RunnableType, RunType, |
| 269 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 270 typename internal::CallbackParamTraits<P2>::StorageType, |
| 271 typename internal::CallbackParamTraits<P3>::StorageType, |
| 272 typename internal::CallbackParamTraits<P4>::StorageType)>( |
| 273 internal::MakeRunnable(functor), p1, p2, p3, p4)); |
| 274 } |
| 275 |
| 276 template <typename Functor, typename P1, typename P2, typename P3, typename P4, |
77 typename P5> | 277 typename P5> |
78 internal::InvokerStorageHolder<internal::InvokerStorage5<Sig,P1, P2, P3, P4, | 278 internal::BindStateHolder< |
79 P5> > | 279 internal::BindState< |
80 Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4, | 280 typename internal::FunctorTraits<Functor>::RunnableType, |
| 281 typename internal::FunctorTraits<Functor>::RunType, |
| 282 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 283 typename internal::CallbackParamTraits<P2>::StorageType, |
| 284 typename internal::CallbackParamTraits<P3>::StorageType, |
| 285 typename internal::CallbackParamTraits<P4>::StorageType, |
| 286 typename internal::CallbackParamTraits<P5>::StorageType)> > |
| 287 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4, |
81 const P5& p5) { | 288 const P5& p5) { |
82 return internal::MakeInvokerStorageHolder( | 289 // Typedefs for how to store and run the functor. |
83 new internal::InvokerStorage5<Sig, P1, P2, P3, P4, P5>( | 290 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
84 f, p1, p2, p3, p4, p5)); | 291 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
85 } | 292 |
86 | 293 // Use RunnableType::RunType instead of RunType above because our |
87 template <typename Sig, typename P1, typename P2, typename P3, typename P4, | 294 // checks should below for bound references need to know what the actual |
| 295 // functor is going to interpret the argument as. |
| 296 typedef internal::FunctionTraits<typename RunnableType::RunType> |
| 297 BoundFunctorTraits; |
| 298 |
| 299 // Do not allow binding a non-const reference parameter. Non-const reference |
| 300 // parameters are disallowed by the Google style guide. Also, binding a |
| 301 // non-const reference parameter can make for subtle bugs because the |
| 302 // invoked function will receive a reference to the stored copy of the |
| 303 // argument and not the original. |
| 304 COMPILE_ASSERT( |
| 305 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
| 306 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
| 307 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value || |
| 308 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value || |
| 309 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ), |
| 310 do_not_bind_functions_with_nonconst_ref); |
| 311 |
| 312 // For methods, we need to be careful for parameter 1. We do not require |
| 313 // a scoped_refptr because BindState<> itself takes care of AddRef() for |
| 314 // methods. We also disallow binding of an array as the method's target |
| 315 // object. |
| 316 COMPILE_ASSERT( |
| 317 internal::HasIsMethodTag<RunnableType>::value || |
| 318 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
| 319 p1_is_refcounted_type_and_needs_scoped_refptr); |
| 320 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
| 321 !is_array<P1>::value, |
| 322 first_bound_argument_to_method_cannot_be_array); |
| 323 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
| 324 p2_is_refcounted_type_and_needs_scoped_refptr); |
| 325 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
| 326 p3_is_refcounted_type_and_needs_scoped_refptr); |
| 327 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value, |
| 328 p4_is_refcounted_type_and_needs_scoped_refptr); |
| 329 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value, |
| 330 p5_is_refcounted_type_and_needs_scoped_refptr); |
| 331 |
| 332 return internal::MakeBindStateHolder( |
| 333 new internal::BindState<RunnableType, RunType, |
| 334 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 335 typename internal::CallbackParamTraits<P2>::StorageType, |
| 336 typename internal::CallbackParamTraits<P3>::StorageType, |
| 337 typename internal::CallbackParamTraits<P4>::StorageType, |
| 338 typename internal::CallbackParamTraits<P5>::StorageType)>( |
| 339 internal::MakeRunnable(functor), p1, p2, p3, p4, p5)); |
| 340 } |
| 341 |
| 342 template <typename Functor, typename P1, typename P2, typename P3, typename P4, |
88 typename P5, typename P6> | 343 typename P5, typename P6> |
89 internal::InvokerStorageHolder<internal::InvokerStorage6<Sig,P1, P2, P3, P4, | 344 internal::BindStateHolder< |
90 P5, P6> > | 345 internal::BindState< |
91 Bind(Sig f, const P1& p1, const P2& p2, const P3& p3, const P4& p4, | 346 typename internal::FunctorTraits<Functor>::RunnableType, |
| 347 typename internal::FunctorTraits<Functor>::RunType, |
| 348 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 349 typename internal::CallbackParamTraits<P2>::StorageType, |
| 350 typename internal::CallbackParamTraits<P3>::StorageType, |
| 351 typename internal::CallbackParamTraits<P4>::StorageType, |
| 352 typename internal::CallbackParamTraits<P5>::StorageType, |
| 353 typename internal::CallbackParamTraits<P6>::StorageType)> > |
| 354 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4, |
92 const P5& p5, const P6& p6) { | 355 const P5& p5, const P6& p6) { |
93 return internal::MakeInvokerStorageHolder( | 356 // Typedefs for how to store and run the functor. |
94 new internal::InvokerStorage6<Sig, P1, P2, P3, P4, P5, P6>( | 357 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; |
95 f, p1, p2, p3, p4, p5, p6)); | 358 typedef typename internal::FunctorTraits<Functor>::RunType RunType; |
96 } | 359 |
97 | 360 // Use RunnableType::RunType instead of RunType above because our |
98 // Specializations to allow binding all the free arguments in a | 361 // checks should below for bound references need to know what the actual |
99 // pre-existing base::Callback<>. This does not give full support for | 362 // functor is going to interpret the argument as. |
100 // currying, but is significantly simpler and addresses the use case | 363 typedef internal::FunctionTraits<typename RunnableType::RunType> |
101 // where a base::Callback<> needs to be invoked on another context/thread. | 364 BoundFunctorTraits; |
102 template <typename Sig, typename P1> | 365 |
103 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1) { | 366 // Do not allow binding a non-const reference parameter. Non-const reference |
104 return base::Bind(&internal::BindMoreFunc1<Sig, P1>, callback, p1); | 367 // parameters are disallowed by the Google style guide. Also, binding a |
105 } | 368 // non-const reference parameter can make for subtle bugs because the |
106 | 369 // invoked function will receive a reference to the stored copy of the |
107 template <typename Sig, typename P1, typename P2> | 370 // argument and not the original. |
108 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 371 COMPILE_ASSERT( |
109 const P2& p2) { | 372 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value || |
110 return base::Bind(&internal::BindMoreFunc2<Sig, P1, P2>, callback, p1, p2); | 373 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value || |
111 } | 374 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value || |
112 | 375 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value || |
113 template <typename Sig, typename P1, typename P2, typename P3> | 376 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value || |
114 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 377 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ), |
115 const P2& p2, const P3& p3) { | 378 do_not_bind_functions_with_nonconst_ref); |
116 return base::Bind(&internal::BindMoreFunc3<Sig, P1, P2, P3>, callback, p1, | 379 |
117 p2, p3); | 380 // For methods, we need to be careful for parameter 1. We do not require |
118 } | 381 // a scoped_refptr because BindState<> itself takes care of AddRef() for |
119 | 382 // methods. We also disallow binding of an array as the method's target |
120 template <typename Sig, typename P1, typename P2, typename P3, typename P4> | 383 // object. |
121 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 384 COMPILE_ASSERT( |
122 const P2& p2, const P3& p3, const P4& p4) { | 385 internal::HasIsMethodTag<RunnableType>::value || |
123 return base::Bind(&internal::BindMoreFunc4<Sig, P1, P2, P3, P4>, callback, | 386 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value, |
124 p1, p2, p3, p4); | 387 p1_is_refcounted_type_and_needs_scoped_refptr); |
125 } | 388 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || |
126 | 389 !is_array<P1>::value, |
127 template <typename Sig, typename P1, typename P2, typename P3, typename P4, | 390 first_bound_argument_to_method_cannot_be_array); |
128 typename P5> | 391 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value, |
129 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 392 p2_is_refcounted_type_and_needs_scoped_refptr); |
130 const P2& p2, const P3& p3, const P4& p4, const P5& p5) { | 393 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value, |
131 return base::Bind(&internal::BindMoreFunc5<Sig, P1, P2, P3, P4, P5>, | 394 p3_is_refcounted_type_and_needs_scoped_refptr); |
132 callback, p1, p2, p3, p4, p5); | 395 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value, |
133 } | 396 p4_is_refcounted_type_and_needs_scoped_refptr); |
134 | 397 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value, |
135 template <typename Sig, typename P1, typename P2, typename P3, typename P4, | 398 p5_is_refcounted_type_and_needs_scoped_refptr); |
136 typename P5, typename P6> | 399 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value, |
137 base::Closure Bind(const base::Callback<Sig>& callback, const P1& p1, | 400 p6_is_refcounted_type_and_needs_scoped_refptr); |
138 const P2& p2, const P3& p3, const P4& p4, const P5& p5, const P6& p6) { | 401 |
139 return base::Bind(&internal::BindMoreFunc6<Sig, P1, P2, P3, P4, P5, P6>, | 402 return internal::MakeBindStateHolder( |
140 callback, p1, p2, p3, p4, p5, p6); | 403 new internal::BindState<RunnableType, RunType, |
| 404 void(typename internal::CallbackParamTraits<P1>::StorageType, |
| 405 typename internal::CallbackParamTraits<P2>::StorageType, |
| 406 typename internal::CallbackParamTraits<P3>::StorageType, |
| 407 typename internal::CallbackParamTraits<P4>::StorageType, |
| 408 typename internal::CallbackParamTraits<P5>::StorageType, |
| 409 typename internal::CallbackParamTraits<P6>::StorageType)>( |
| 410 internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6)); |
141 } | 411 } |
142 | 412 |
143 } // namespace base | 413 } // namespace base |
144 | 414 |
145 #endif // BASE_BIND_H_ | 415 #endif // BASE_BIND_H_ |
OLD | NEW |