security/sandbox/chromium/base/bind.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 // This file was GENERATED by command:
michael@0 2 // pump.py bind.h.pump
michael@0 3 // DO NOT EDIT BY HAND!!!
michael@0 4
michael@0 5
michael@0 6 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
michael@0 7 // Use of this source code is governed by a BSD-style license that can be
michael@0 8 // found in the LICENSE file.
michael@0 9
michael@0 10 #ifndef BASE_BIND_H_
michael@0 11 #define BASE_BIND_H_
michael@0 12
michael@0 13 #include "base/bind_internal.h"
michael@0 14 #include "base/callback_internal.h"
michael@0 15
michael@0 16 // -----------------------------------------------------------------------------
michael@0 17 // Usage documentation
michael@0 18 // -----------------------------------------------------------------------------
michael@0 19 //
michael@0 20 // See base/callback.h for documentation.
michael@0 21 //
michael@0 22 //
michael@0 23 // -----------------------------------------------------------------------------
michael@0 24 // Implementation notes
michael@0 25 // -----------------------------------------------------------------------------
michael@0 26 //
michael@0 27 // If you're reading the implementation, before proceeding further, you should
michael@0 28 // read the top comment of base/bind_internal.h for a definition of common
michael@0 29 // terms and concepts.
michael@0 30 //
michael@0 31 // RETURN TYPES
michael@0 32 //
michael@0 33 // Though Bind()'s result is meant to be stored in a Callback<> type, it
michael@0 34 // cannot actually return the exact type without requiring a large amount
michael@0 35 // of extra template specializations. The problem is that in order to
michael@0 36 // discern the correct specialization of Callback<>, Bind would need to
michael@0 37 // unwrap the function signature to determine the signature's arity, and
michael@0 38 // whether or not it is a method.
michael@0 39 //
michael@0 40 // Each unique combination of (arity, function_type, num_prebound) where
michael@0 41 // function_type is one of {function, method, const_method} would require
michael@0 42 // one specialization. We eventually have to do a similar number of
michael@0 43 // specializations anyways in the implementation (see the Invoker<>,
michael@0 44 // classes). However, it is avoidable in Bind if we return the result
michael@0 45 // via an indirection like we do below.
michael@0 46 //
michael@0 47 // TODO(ajwong): We might be able to avoid this now, but need to test.
michael@0 48 //
michael@0 49 // It is possible to move most of the COMPILE_ASSERT asserts into BindState<>,
michael@0 50 // but it feels a little nicer to have the asserts here so people do not
michael@0 51 // need to crack open bind_internal.h. On the other hand, it makes Bind()
michael@0 52 // harder to read.
michael@0 53
michael@0 54 namespace base {
michael@0 55
michael@0 56 template <typename Functor>
michael@0 57 base::Callback<
michael@0 58 typename internal::BindState<
michael@0 59 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 60 typename internal::FunctorTraits<Functor>::RunType,
michael@0 61 void()>
michael@0 62 ::UnboundRunType>
michael@0 63 Bind(Functor functor) {
michael@0 64 // Typedefs for how to store and run the functor.
michael@0 65 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 66 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 67
michael@0 68 // Use RunnableType::RunType instead of RunType above because our
michael@0 69 // checks should below for bound references need to know what the actual
michael@0 70 // functor is going to interpret the argument as.
michael@0 71 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 72 BoundFunctorTraits;
michael@0 73
michael@0 74 typedef internal::BindState<RunnableType, RunType, void()> BindState;
michael@0 75
michael@0 76
michael@0 77 return Callback<typename BindState::UnboundRunType>(
michael@0 78 new BindState(internal::MakeRunnable(functor)));
michael@0 79 }
michael@0 80
michael@0 81 template <typename Functor, typename P1>
michael@0 82 base::Callback<
michael@0 83 typename internal::BindState<
michael@0 84 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 85 typename internal::FunctorTraits<Functor>::RunType,
michael@0 86 void(typename internal::CallbackParamTraits<P1>::StorageType)>
michael@0 87 ::UnboundRunType>
michael@0 88 Bind(Functor functor, const P1& p1) {
michael@0 89 // Typedefs for how to store and run the functor.
michael@0 90 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 91 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 92
michael@0 93 // Use RunnableType::RunType instead of RunType above because our
michael@0 94 // checks should below for bound references need to know what the actual
michael@0 95 // functor is going to interpret the argument as.
michael@0 96 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 97 BoundFunctorTraits;
michael@0 98
michael@0 99 // Do not allow binding a non-const reference parameter. Non-const reference
michael@0 100 // parameters are disallowed by the Google style guide. Also, binding a
michael@0 101 // non-const reference parameter can make for subtle bugs because the
michael@0 102 // invoked function will receive a reference to the stored copy of the
michael@0 103 // argument and not the original.
michael@0 104 COMPILE_ASSERT(
michael@0 105 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ),
michael@0 106 do_not_bind_functions_with_nonconst_ref);
michael@0 107
michael@0 108 // For methods, we need to be careful for parameter 1. We do not require
michael@0 109 // a scoped_refptr because BindState<> itself takes care of AddRef() for
michael@0 110 // methods. We also disallow binding of an array as the method's target
michael@0 111 // object.
michael@0 112 COMPILE_ASSERT(
michael@0 113 internal::HasIsMethodTag<RunnableType>::value ||
michael@0 114 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
michael@0 115 p1_is_refcounted_type_and_needs_scoped_refptr);
michael@0 116 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
michael@0 117 !is_array<P1>::value,
michael@0 118 first_bound_argument_to_method_cannot_be_array);
michael@0 119 typedef internal::BindState<RunnableType, RunType,
michael@0 120 void(typename internal::CallbackParamTraits<P1>::StorageType)> BindState;
michael@0 121
michael@0 122
michael@0 123 return Callback<typename BindState::UnboundRunType>(
michael@0 124 new BindState(internal::MakeRunnable(functor), p1));
michael@0 125 }
michael@0 126
michael@0 127 template <typename Functor, typename P1, typename P2>
michael@0 128 base::Callback<
michael@0 129 typename internal::BindState<
michael@0 130 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 131 typename internal::FunctorTraits<Functor>::RunType,
michael@0 132 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 133 typename internal::CallbackParamTraits<P2>::StorageType)>
michael@0 134 ::UnboundRunType>
michael@0 135 Bind(Functor functor, const P1& p1, const P2& p2) {
michael@0 136 // Typedefs for how to store and run the functor.
michael@0 137 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 138 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 139
michael@0 140 // Use RunnableType::RunType instead of RunType above because our
michael@0 141 // checks should below for bound references need to know what the actual
michael@0 142 // functor is going to interpret the argument as.
michael@0 143 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 144 BoundFunctorTraits;
michael@0 145
michael@0 146 // Do not allow binding a non-const reference parameter. Non-const reference
michael@0 147 // parameters are disallowed by the Google style guide. Also, binding a
michael@0 148 // non-const reference parameter can make for subtle bugs because the
michael@0 149 // invoked function will receive a reference to the stored copy of the
michael@0 150 // argument and not the original.
michael@0 151 COMPILE_ASSERT(
michael@0 152 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
michael@0 153 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ),
michael@0 154 do_not_bind_functions_with_nonconst_ref);
michael@0 155
michael@0 156 // For methods, we need to be careful for parameter 1. We do not require
michael@0 157 // a scoped_refptr because BindState<> itself takes care of AddRef() for
michael@0 158 // methods. We also disallow binding of an array as the method's target
michael@0 159 // object.
michael@0 160 COMPILE_ASSERT(
michael@0 161 internal::HasIsMethodTag<RunnableType>::value ||
michael@0 162 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
michael@0 163 p1_is_refcounted_type_and_needs_scoped_refptr);
michael@0 164 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
michael@0 165 !is_array<P1>::value,
michael@0 166 first_bound_argument_to_method_cannot_be_array);
michael@0 167 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
michael@0 168 p2_is_refcounted_type_and_needs_scoped_refptr);
michael@0 169 typedef internal::BindState<RunnableType, RunType,
michael@0 170 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 171 typename internal::CallbackParamTraits<P2>::StorageType)> BindState;
michael@0 172
michael@0 173
michael@0 174 return Callback<typename BindState::UnboundRunType>(
michael@0 175 new BindState(internal::MakeRunnable(functor), p1, p2));
michael@0 176 }
michael@0 177
michael@0 178 template <typename Functor, typename P1, typename P2, typename P3>
michael@0 179 base::Callback<
michael@0 180 typename internal::BindState<
michael@0 181 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 182 typename internal::FunctorTraits<Functor>::RunType,
michael@0 183 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 184 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 185 typename internal::CallbackParamTraits<P3>::StorageType)>
michael@0 186 ::UnboundRunType>
michael@0 187 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) {
michael@0 188 // Typedefs for how to store and run the functor.
michael@0 189 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 190 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 191
michael@0 192 // Use RunnableType::RunType instead of RunType above because our
michael@0 193 // checks should below for bound references need to know what the actual
michael@0 194 // functor is going to interpret the argument as.
michael@0 195 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 196 BoundFunctorTraits;
michael@0 197
michael@0 198 // Do not allow binding a non-const reference parameter. Non-const reference
michael@0 199 // parameters are disallowed by the Google style guide. Also, binding a
michael@0 200 // non-const reference parameter can make for subtle bugs because the
michael@0 201 // invoked function will receive a reference to the stored copy of the
michael@0 202 // argument and not the original.
michael@0 203 COMPILE_ASSERT(
michael@0 204 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
michael@0 205 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
michael@0 206 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ),
michael@0 207 do_not_bind_functions_with_nonconst_ref);
michael@0 208
michael@0 209 // For methods, we need to be careful for parameter 1. We do not require
michael@0 210 // a scoped_refptr because BindState<> itself takes care of AddRef() for
michael@0 211 // methods. We also disallow binding of an array as the method's target
michael@0 212 // object.
michael@0 213 COMPILE_ASSERT(
michael@0 214 internal::HasIsMethodTag<RunnableType>::value ||
michael@0 215 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
michael@0 216 p1_is_refcounted_type_and_needs_scoped_refptr);
michael@0 217 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
michael@0 218 !is_array<P1>::value,
michael@0 219 first_bound_argument_to_method_cannot_be_array);
michael@0 220 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
michael@0 221 p2_is_refcounted_type_and_needs_scoped_refptr);
michael@0 222 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
michael@0 223 p3_is_refcounted_type_and_needs_scoped_refptr);
michael@0 224 typedef internal::BindState<RunnableType, RunType,
michael@0 225 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 226 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 227 typename internal::CallbackParamTraits<P3>::StorageType)> BindState;
michael@0 228
michael@0 229
michael@0 230 return Callback<typename BindState::UnboundRunType>(
michael@0 231 new BindState(internal::MakeRunnable(functor), p1, p2, p3));
michael@0 232 }
michael@0 233
michael@0 234 template <typename Functor, typename P1, typename P2, typename P3, typename P4>
michael@0 235 base::Callback<
michael@0 236 typename internal::BindState<
michael@0 237 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 238 typename internal::FunctorTraits<Functor>::RunType,
michael@0 239 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 240 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 241 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 242 typename internal::CallbackParamTraits<P4>::StorageType)>
michael@0 243 ::UnboundRunType>
michael@0 244 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
michael@0 245 // Typedefs for how to store and run the functor.
michael@0 246 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 247 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 248
michael@0 249 // Use RunnableType::RunType instead of RunType above because our
michael@0 250 // checks should below for bound references need to know what the actual
michael@0 251 // functor is going to interpret the argument as.
michael@0 252 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 253 BoundFunctorTraits;
michael@0 254
michael@0 255 // Do not allow binding a non-const reference parameter. Non-const reference
michael@0 256 // parameters are disallowed by the Google style guide. Also, binding a
michael@0 257 // non-const reference parameter can make for subtle bugs because the
michael@0 258 // invoked function will receive a reference to the stored copy of the
michael@0 259 // argument and not the original.
michael@0 260 COMPILE_ASSERT(
michael@0 261 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
michael@0 262 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
michael@0 263 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
michael@0 264 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ),
michael@0 265 do_not_bind_functions_with_nonconst_ref);
michael@0 266
michael@0 267 // For methods, we need to be careful for parameter 1. We do not require
michael@0 268 // a scoped_refptr because BindState<> itself takes care of AddRef() for
michael@0 269 // methods. We also disallow binding of an array as the method's target
michael@0 270 // object.
michael@0 271 COMPILE_ASSERT(
michael@0 272 internal::HasIsMethodTag<RunnableType>::value ||
michael@0 273 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
michael@0 274 p1_is_refcounted_type_and_needs_scoped_refptr);
michael@0 275 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
michael@0 276 !is_array<P1>::value,
michael@0 277 first_bound_argument_to_method_cannot_be_array);
michael@0 278 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
michael@0 279 p2_is_refcounted_type_and_needs_scoped_refptr);
michael@0 280 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
michael@0 281 p3_is_refcounted_type_and_needs_scoped_refptr);
michael@0 282 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
michael@0 283 p4_is_refcounted_type_and_needs_scoped_refptr);
michael@0 284 typedef internal::BindState<RunnableType, RunType,
michael@0 285 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 286 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 287 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 288 typename internal::CallbackParamTraits<P4>::StorageType)> BindState;
michael@0 289
michael@0 290
michael@0 291 return Callback<typename BindState::UnboundRunType>(
michael@0 292 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4));
michael@0 293 }
michael@0 294
michael@0 295 template <typename Functor, typename P1, typename P2, typename P3, typename P4,
michael@0 296 typename P5>
michael@0 297 base::Callback<
michael@0 298 typename internal::BindState<
michael@0 299 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 300 typename internal::FunctorTraits<Functor>::RunType,
michael@0 301 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 302 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 303 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 304 typename internal::CallbackParamTraits<P4>::StorageType,
michael@0 305 typename internal::CallbackParamTraits<P5>::StorageType)>
michael@0 306 ::UnboundRunType>
michael@0 307 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
michael@0 308 const P5& p5) {
michael@0 309 // Typedefs for how to store and run the functor.
michael@0 310 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 311 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 312
michael@0 313 // Use RunnableType::RunType instead of RunType above because our
michael@0 314 // checks should below for bound references need to know what the actual
michael@0 315 // functor is going to interpret the argument as.
michael@0 316 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 317 BoundFunctorTraits;
michael@0 318
michael@0 319 // Do not allow binding a non-const reference parameter. Non-const reference
michael@0 320 // parameters are disallowed by the Google style guide. Also, binding a
michael@0 321 // non-const reference parameter can make for subtle bugs because the
michael@0 322 // invoked function will receive a reference to the stored copy of the
michael@0 323 // argument and not the original.
michael@0 324 COMPILE_ASSERT(
michael@0 325 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
michael@0 326 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
michael@0 327 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
michael@0 328 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
michael@0 329 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ),
michael@0 330 do_not_bind_functions_with_nonconst_ref);
michael@0 331
michael@0 332 // For methods, we need to be careful for parameter 1. We do not require
michael@0 333 // a scoped_refptr because BindState<> itself takes care of AddRef() for
michael@0 334 // methods. We also disallow binding of an array as the method's target
michael@0 335 // object.
michael@0 336 COMPILE_ASSERT(
michael@0 337 internal::HasIsMethodTag<RunnableType>::value ||
michael@0 338 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
michael@0 339 p1_is_refcounted_type_and_needs_scoped_refptr);
michael@0 340 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
michael@0 341 !is_array<P1>::value,
michael@0 342 first_bound_argument_to_method_cannot_be_array);
michael@0 343 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
michael@0 344 p2_is_refcounted_type_and_needs_scoped_refptr);
michael@0 345 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
michael@0 346 p3_is_refcounted_type_and_needs_scoped_refptr);
michael@0 347 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
michael@0 348 p4_is_refcounted_type_and_needs_scoped_refptr);
michael@0 349 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
michael@0 350 p5_is_refcounted_type_and_needs_scoped_refptr);
michael@0 351 typedef internal::BindState<RunnableType, RunType,
michael@0 352 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 353 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 354 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 355 typename internal::CallbackParamTraits<P4>::StorageType,
michael@0 356 typename internal::CallbackParamTraits<P5>::StorageType)> BindState;
michael@0 357
michael@0 358
michael@0 359 return Callback<typename BindState::UnboundRunType>(
michael@0 360 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5));
michael@0 361 }
michael@0 362
michael@0 363 template <typename Functor, typename P1, typename P2, typename P3, typename P4,
michael@0 364 typename P5, typename P6>
michael@0 365 base::Callback<
michael@0 366 typename internal::BindState<
michael@0 367 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 368 typename internal::FunctorTraits<Functor>::RunType,
michael@0 369 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 370 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 371 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 372 typename internal::CallbackParamTraits<P4>::StorageType,
michael@0 373 typename internal::CallbackParamTraits<P5>::StorageType,
michael@0 374 typename internal::CallbackParamTraits<P6>::StorageType)>
michael@0 375 ::UnboundRunType>
michael@0 376 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
michael@0 377 const P5& p5, const P6& p6) {
michael@0 378 // Typedefs for how to store and run the functor.
michael@0 379 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 380 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 381
michael@0 382 // Use RunnableType::RunType instead of RunType above because our
michael@0 383 // checks should below for bound references need to know what the actual
michael@0 384 // functor is going to interpret the argument as.
michael@0 385 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 386 BoundFunctorTraits;
michael@0 387
michael@0 388 // Do not allow binding a non-const reference parameter. Non-const reference
michael@0 389 // parameters are disallowed by the Google style guide. Also, binding a
michael@0 390 // non-const reference parameter can make for subtle bugs because the
michael@0 391 // invoked function will receive a reference to the stored copy of the
michael@0 392 // argument and not the original.
michael@0 393 COMPILE_ASSERT(
michael@0 394 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
michael@0 395 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
michael@0 396 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
michael@0 397 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
michael@0 398 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
michael@0 399 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ),
michael@0 400 do_not_bind_functions_with_nonconst_ref);
michael@0 401
michael@0 402 // For methods, we need to be careful for parameter 1. We do not require
michael@0 403 // a scoped_refptr because BindState<> itself takes care of AddRef() for
michael@0 404 // methods. We also disallow binding of an array as the method's target
michael@0 405 // object.
michael@0 406 COMPILE_ASSERT(
michael@0 407 internal::HasIsMethodTag<RunnableType>::value ||
michael@0 408 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
michael@0 409 p1_is_refcounted_type_and_needs_scoped_refptr);
michael@0 410 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
michael@0 411 !is_array<P1>::value,
michael@0 412 first_bound_argument_to_method_cannot_be_array);
michael@0 413 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
michael@0 414 p2_is_refcounted_type_and_needs_scoped_refptr);
michael@0 415 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
michael@0 416 p3_is_refcounted_type_and_needs_scoped_refptr);
michael@0 417 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
michael@0 418 p4_is_refcounted_type_and_needs_scoped_refptr);
michael@0 419 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
michael@0 420 p5_is_refcounted_type_and_needs_scoped_refptr);
michael@0 421 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
michael@0 422 p6_is_refcounted_type_and_needs_scoped_refptr);
michael@0 423 typedef internal::BindState<RunnableType, RunType,
michael@0 424 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 425 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 426 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 427 typename internal::CallbackParamTraits<P4>::StorageType,
michael@0 428 typename internal::CallbackParamTraits<P5>::StorageType,
michael@0 429 typename internal::CallbackParamTraits<P6>::StorageType)> BindState;
michael@0 430
michael@0 431
michael@0 432 return Callback<typename BindState::UnboundRunType>(
michael@0 433 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6));
michael@0 434 }
michael@0 435
michael@0 436 template <typename Functor, typename P1, typename P2, typename P3, typename P4,
michael@0 437 typename P5, typename P6, typename P7>
michael@0 438 base::Callback<
michael@0 439 typename internal::BindState<
michael@0 440 typename internal::FunctorTraits<Functor>::RunnableType,
michael@0 441 typename internal::FunctorTraits<Functor>::RunType,
michael@0 442 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 443 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 444 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 445 typename internal::CallbackParamTraits<P4>::StorageType,
michael@0 446 typename internal::CallbackParamTraits<P5>::StorageType,
michael@0 447 typename internal::CallbackParamTraits<P6>::StorageType,
michael@0 448 typename internal::CallbackParamTraits<P7>::StorageType)>
michael@0 449 ::UnboundRunType>
michael@0 450 Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
michael@0 451 const P5& p5, const P6& p6, const P7& p7) {
michael@0 452 // Typedefs for how to store and run the functor.
michael@0 453 typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
michael@0 454 typedef typename internal::FunctorTraits<Functor>::RunType RunType;
michael@0 455
michael@0 456 // Use RunnableType::RunType instead of RunType above because our
michael@0 457 // checks should below for bound references need to know what the actual
michael@0 458 // functor is going to interpret the argument as.
michael@0 459 typedef internal::FunctionTraits<typename RunnableType::RunType>
michael@0 460 BoundFunctorTraits;
michael@0 461
michael@0 462 // Do not allow binding a non-const reference parameter. Non-const reference
michael@0 463 // parameters are disallowed by the Google style guide. Also, binding a
michael@0 464 // non-const reference parameter can make for subtle bugs because the
michael@0 465 // invoked function will receive a reference to the stored copy of the
michael@0 466 // argument and not the original.
michael@0 467 COMPILE_ASSERT(
michael@0 468 !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
michael@0 469 is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
michael@0 470 is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
michael@0 471 is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
michael@0 472 is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
michael@0 473 is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ||
michael@0 474 is_non_const_reference<typename BoundFunctorTraits::A7Type>::value ),
michael@0 475 do_not_bind_functions_with_nonconst_ref);
michael@0 476
michael@0 477 // For methods, we need to be careful for parameter 1. We do not require
michael@0 478 // a scoped_refptr because BindState<> itself takes care of AddRef() for
michael@0 479 // methods. We also disallow binding of an array as the method's target
michael@0 480 // object.
michael@0 481 COMPILE_ASSERT(
michael@0 482 internal::HasIsMethodTag<RunnableType>::value ||
michael@0 483 !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
michael@0 484 p1_is_refcounted_type_and_needs_scoped_refptr);
michael@0 485 COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
michael@0 486 !is_array<P1>::value,
michael@0 487 first_bound_argument_to_method_cannot_be_array);
michael@0 488 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
michael@0 489 p2_is_refcounted_type_and_needs_scoped_refptr);
michael@0 490 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
michael@0 491 p3_is_refcounted_type_and_needs_scoped_refptr);
michael@0 492 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
michael@0 493 p4_is_refcounted_type_and_needs_scoped_refptr);
michael@0 494 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
michael@0 495 p5_is_refcounted_type_and_needs_scoped_refptr);
michael@0 496 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
michael@0 497 p6_is_refcounted_type_and_needs_scoped_refptr);
michael@0 498 COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P7>::value,
michael@0 499 p7_is_refcounted_type_and_needs_scoped_refptr);
michael@0 500 typedef internal::BindState<RunnableType, RunType,
michael@0 501 void(typename internal::CallbackParamTraits<P1>::StorageType,
michael@0 502 typename internal::CallbackParamTraits<P2>::StorageType,
michael@0 503 typename internal::CallbackParamTraits<P3>::StorageType,
michael@0 504 typename internal::CallbackParamTraits<P4>::StorageType,
michael@0 505 typename internal::CallbackParamTraits<P5>::StorageType,
michael@0 506 typename internal::CallbackParamTraits<P6>::StorageType,
michael@0 507 typename internal::CallbackParamTraits<P7>::StorageType)> BindState;
michael@0 508
michael@0 509
michael@0 510 return Callback<typename BindState::UnboundRunType>(
michael@0 511 new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6,
michael@0 512 p7));
michael@0 513 }
michael@0 514
michael@0 515 } // namespace base
michael@0 516
michael@0 517 #endif // BASE_BIND_H_

mercurial