| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef BASE_BIND_INTERNAL_H_ | |
| 6 #define BASE_BIND_INTERNAL_H_ | |
| 7 | |
| 8 #include "base/bind_helpers.h" | |
| 9 #include "base/callback_internal.h" | |
| 10 #include "base/memory/raw_scoped_refptr_mismatch_checker.h" | |
| 11 #include "base/memory/weak_ptr.h" | |
| 12 #include "base/template_util.h" | |
| 13 #include "base/tuple.h" | |
| 14 #include "build/build_config.h" | |
| 15 | |
| 16 #if defined(OS_WIN) | |
| 17 #include "base/bind_internal_win.h" | |
| 18 #endif | |
| 19 | |
| 20 namespace base { | |
| 21 namespace internal { | |
| 22 | |
| 23 // See base/callback.h for user documentation. | |
| 24 // | |
| 25 // | |
| 26 // CONCEPTS: | |
| 27 // Runnable -- A type (really a type class) that has a single Run() method | |
| 28 // and a RunType typedef that corresponds to the type of Run(). | |
| 29 // A Runnable can declare that it should treated like a method | |
| 30 // call by including a typedef named IsMethod. The value of | |
| 31 // this typedef is NOT inspected, only the existence. When a | |
| 32 // Runnable declares itself a method, Bind() will enforce special | |
| 33 // refcounting + WeakPtr handling semantics for the first | |
| 34 // parameter which is expected to be an object. | |
| 35 // Functor -- A copyable type representing something that should be called. | |
| 36 // All function pointers, Callback<>, and Runnables are functors | |
| 37 // even if the invocation syntax differs. | |
| 38 // RunType -- A function type (as opposed to function _pointer_ type) for | |
| 39 // a Run() function. Usually just a convenience typedef. | |
| 40 // (Bound)ArgsType -- A function type that is being (ab)used to store the | |
| 41 // types of set of arguments. The "return" type is always | |
| 42 // void here. We use this hack so that we do not need | |
| 43 // a new type name for each arity of type. (eg., | |
| 44 // BindState1, BindState2). This makes forward | |
| 45 // declarations and friending much much easier. | |
| 46 // | |
| 47 // Types: | |
| 48 // RunnableAdapter<> -- Wraps the various "function" pointer types into an | |
| 49 // object that adheres to the Runnable interface. | |
| 50 // ForceVoidReturn<> -- Helper class for translating function signatures to | |
| 51 // equivalent forms with a "void" return type. | |
| 52 // FunctorTraits<> -- Type traits used determine the correct RunType and | |
| 53 // RunnableType for a Functor. This is where function | |
| 54 // signature adapters are applied. | |
| 55 // MakeRunnable<> -- Takes a Functor and returns an object in the Runnable | |
| 56 // type class that represents the underlying Functor. | |
| 57 // There are |O(1)| MakeRunnable types. | |
| 58 // InvokeHelper<> -- Take a Runnable + arguments and actully invokes it. | |
| 59 // Handle the differing syntaxes needed for WeakPtr<> | |
| 60 // support, and for ignoring return values. This is separate | |
| 61 // from Invoker to avoid creating multiple version of | |
| 62 // Invoker<>. | |
| 63 // Invoker<> -- Unwraps the curried parameters and executes the Runnable. | |
| 64 // BindState<> -- Stores the curried parameters, and is the main entry point | |
| 65 // into the Bind() system, doing most of the type resolution. | |
| 66 // There are ARITY BindState types. | |
| 67 | |
| 68 // HasNonConstReferenceParam selects true_type when any of the parameters in | |
| 69 // |Sig| is a non-const reference. | |
| 70 // Implementation note: This non-specialized case handles zero-arity case only. | |
| 71 // Non-zero-arity cases should be handled by the specialization below. | |
| 72 template <typename Sig> | |
| 73 struct HasNonConstReferenceParam : false_type {}; | |
| 74 | |
| 75 // Implementation note: Select true_type if the first parameter is a non-const | |
| 76 // reference. Otherwise, skip the first parameter and check rest of parameters | |
| 77 // recursively. | |
| 78 template <typename R, typename T, typename... Args> | |
| 79 struct HasNonConstReferenceParam<R(T, Args...)> | |
| 80 : SelectType<is_non_const_reference<T>::value, | |
| 81 true_type, | |
| 82 HasNonConstReferenceParam<R(Args...)>>::Type {}; | |
| 83 | |
| 84 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw | |
| 85 // pointer to a RefCounted type. | |
| 86 // Implementation note: This non-specialized case handles zero-arity case only. | |
| 87 // Non-zero-arity cases should be handled by the specialization below. | |
| 88 template <typename... Args> | |
| 89 struct HasRefCountedTypeAsRawPtr : false_type {}; | |
| 90 | |
| 91 // Implementation note: Select true_type if the first parameter is a raw pointer | |
| 92 // to a RefCounted type. Otherwise, skip the first parameter and check rest of | |
| 93 // parameters recursively. | |
| 94 template <typename T, typename... Args> | |
| 95 struct HasRefCountedTypeAsRawPtr<T, Args...> | |
| 96 : SelectType<NeedsScopedRefptrButGetsRawPtr<T>::value, | |
| 97 true_type, | |
| 98 HasRefCountedTypeAsRawPtr<Args...>>::Type {}; | |
| 99 | |
| 100 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first | |
| 101 // item of |Args| is an array type. | |
| 102 // Implementation note: This non-specialized case handles !is_method case and | |
| 103 // zero-arity case only. Other cases should be handled by the specialization | |
| 104 // below. | |
| 105 template <bool is_method, typename... Args> | |
| 106 struct BindsArrayToFirstArg : false_type {}; | |
| 107 | |
| 108 template <typename T, typename... Args> | |
| 109 struct BindsArrayToFirstArg<true, T, Args...> : is_array<T> {}; | |
| 110 | |
| 111 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except | |
| 112 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument. | |
| 113 // Implementation note: This non-specialized case handles !is_method case and | |
| 114 // zero-arity case only. Other cases should be handled by the specialization | |
| 115 // below. | |
| 116 template <bool is_method, typename... Args> | |
| 117 struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {}; | |
| 118 | |
| 119 template <typename T, typename... Args> | |
| 120 struct HasRefCountedParamAsRawPtr<true, T, Args...> | |
| 121 : HasRefCountedTypeAsRawPtr<Args...> {}; | |
| 122 | |
| 123 // RunnableAdapter<> | |
| 124 // | |
| 125 // The RunnableAdapter<> templates provide a uniform interface for invoking | |
| 126 // a function pointer, method pointer, or const method pointer. The adapter | |
| 127 // exposes a Run() method with an appropriate signature. Using this wrapper | |
| 128 // allows for writing code that supports all three pointer types without | |
| 129 // undue repetition. Without it, a lot of code would need to be repeated 3 | |
| 130 // times. | |
| 131 // | |
| 132 // For method pointers and const method pointers the first argument to Run() | |
| 133 // is considered to be the received of the method. This is similar to STL's | |
| 134 // mem_fun(). | |
| 135 // | |
| 136 // This class also exposes a RunType typedef that is the function type of the | |
| 137 // Run() function. | |
| 138 // | |
| 139 // If and only if the wrapper contains a method or const method pointer, an | |
| 140 // IsMethod typedef is exposed. The existence of this typedef (NOT the value) | |
| 141 // marks that the wrapper should be considered a method wrapper. | |
| 142 | |
| 143 template <typename Functor> | |
| 144 class RunnableAdapter; | |
| 145 | |
| 146 // Function. | |
| 147 template <typename R, typename... Args> | |
| 148 class RunnableAdapter<R(*)(Args...)> { | |
| 149 public: | |
| 150 typedef R (RunType)(Args...); | |
| 151 | |
| 152 explicit RunnableAdapter(R(*function)(Args...)) | |
| 153 : function_(function) { | |
| 154 } | |
| 155 | |
| 156 R Run(typename CallbackParamTraits<Args>::ForwardType... args) { | |
| 157 return function_(CallbackForward(args)...); | |
| 158 } | |
| 159 | |
| 160 private: | |
| 161 R (*function_)(Args...); | |
| 162 }; | |
| 163 | |
| 164 // Method. | |
| 165 template <typename R, typename T, typename... Args> | |
| 166 class RunnableAdapter<R(T::*)(Args...)> { | |
| 167 public: | |
| 168 typedef R (RunType)(T*, Args...); | |
| 169 typedef true_type IsMethod; | |
| 170 | |
| 171 explicit RunnableAdapter(R(T::*method)(Args...)) | |
| 172 : method_(method) { | |
| 173 } | |
| 174 | |
| 175 R Run(T* object, typename CallbackParamTraits<Args>::ForwardType... args) { | |
| 176 return (object->*method_)(CallbackForward(args)...); | |
| 177 } | |
| 178 | |
| 179 private: | |
| 180 R (T::*method_)(Args...); | |
| 181 }; | |
| 182 | |
| 183 // Const Method. | |
| 184 template <typename R, typename T, typename... Args> | |
| 185 class RunnableAdapter<R(T::*)(Args...) const> { | |
| 186 public: | |
| 187 typedef R (RunType)(const T*, Args...); | |
| 188 typedef true_type IsMethod; | |
| 189 | |
| 190 explicit RunnableAdapter(R(T::*method)(Args...) const) | |
| 191 : method_(method) { | |
| 192 } | |
| 193 | |
| 194 R Run(const T* object, | |
| 195 typename CallbackParamTraits<Args>::ForwardType... args) { | |
| 196 return (object->*method_)(CallbackForward(args)...); | |
| 197 } | |
| 198 | |
| 199 private: | |
| 200 R (T::*method_)(Args...) const; | |
| 201 }; | |
| 202 | |
| 203 | |
| 204 // ForceVoidReturn<> | |
| 205 // | |
| 206 // Set of templates that support forcing the function return type to void. | |
| 207 template <typename Sig> | |
| 208 struct ForceVoidReturn; | |
| 209 | |
| 210 template <typename R, typename... Args> | |
| 211 struct ForceVoidReturn<R(Args...)> { | |
| 212 typedef void(RunType)(Args...); | |
| 213 }; | |
| 214 | |
| 215 | |
| 216 // FunctorTraits<> | |
| 217 // | |
| 218 // See description at top of file. | |
| 219 template <typename T> | |
| 220 struct FunctorTraits { | |
| 221 typedef RunnableAdapter<T> RunnableType; | |
| 222 typedef typename RunnableType::RunType RunType; | |
| 223 }; | |
| 224 | |
| 225 template <typename T> | |
| 226 struct FunctorTraits<IgnoreResultHelper<T>> { | |
| 227 typedef typename FunctorTraits<T>::RunnableType RunnableType; | |
| 228 typedef typename ForceVoidReturn< | |
| 229 typename RunnableType::RunType>::RunType RunType; | |
| 230 }; | |
| 231 | |
| 232 template <typename T> | |
| 233 struct FunctorTraits<Callback<T>> { | |
| 234 typedef Callback<T> RunnableType; | |
| 235 typedef typename Callback<T>::RunType RunType; | |
| 236 }; | |
| 237 | |
| 238 | |
| 239 // MakeRunnable<> | |
| 240 // | |
| 241 // Converts a passed in functor to a RunnableType using type inference. | |
| 242 | |
| 243 template <typename T> | |
| 244 typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) { | |
| 245 return RunnableAdapter<T>(t); | |
| 246 } | |
| 247 | |
| 248 template <typename T> | |
| 249 typename FunctorTraits<T>::RunnableType | |
| 250 MakeRunnable(const IgnoreResultHelper<T>& t) { | |
| 251 return MakeRunnable(t.functor_); | |
| 252 } | |
| 253 | |
| 254 template <typename T> | |
| 255 const typename FunctorTraits<Callback<T>>::RunnableType& | |
| 256 MakeRunnable(const Callback<T>& t) { | |
| 257 DCHECK(!t.is_null()); | |
| 258 return t; | |
| 259 } | |
| 260 | |
| 261 | |
| 262 // InvokeHelper<> | |
| 263 // | |
| 264 // There are 3 logical InvokeHelper<> specializations: normal, void-return, | |
| 265 // WeakCalls. | |
| 266 // | |
| 267 // The normal type just calls the underlying runnable. | |
| 268 // | |
| 269 // We need a InvokeHelper to handle void return types in order to support | |
| 270 // IgnoreResult(). Normally, if the Runnable's RunType had a void return, | |
| 271 // the template system would just accept "return functor.Run()" ignoring | |
| 272 // the fact that a void function is being used with return. This piece of | |
| 273 // sugar breaks though when the Runnable's RunType is not void. Thus, we | |
| 274 // need a partial specialization to change the syntax to drop the "return" | |
| 275 // from the invocation call. | |
| 276 // | |
| 277 // WeakCalls similarly need special syntax that is applied to the first | |
| 278 // argument to check if they should no-op themselves. | |
| 279 template <bool IsWeakCall, typename ReturnType, typename Runnable, | |
| 280 typename ArgsType> | |
| 281 struct InvokeHelper; | |
| 282 | |
| 283 template <typename ReturnType, typename Runnable, typename... Args> | |
| 284 struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> { | |
| 285 static ReturnType MakeItSo(Runnable runnable, Args... args) { | |
| 286 return runnable.Run(CallbackForward(args)...); | |
| 287 } | |
| 288 }; | |
| 289 | |
| 290 template <typename Runnable, typename... Args> | |
| 291 struct InvokeHelper<false, void, Runnable, TypeList<Args...>> { | |
| 292 static void MakeItSo(Runnable runnable, Args... args) { | |
| 293 runnable.Run(CallbackForward(args)...); | |
| 294 } | |
| 295 }; | |
| 296 | |
| 297 template <typename Runnable, typename BoundWeakPtr, typename... Args> | |
| 298 struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> { | |
| 299 static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) { | |
| 300 if (!weak_ptr.get()) { | |
| 301 return; | |
| 302 } | |
| 303 runnable.Run(weak_ptr.get(), CallbackForward(args)...); | |
| 304 } | |
| 305 }; | |
| 306 | |
| 307 #if !defined(_MSC_VER) | |
| 308 | |
| 309 template <typename ReturnType, typename Runnable, typename ArgsType> | |
| 310 struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { | |
| 311 // WeakCalls are only supported for functions with a void return type. | |
| 312 // Otherwise, the function result would be undefined if the the WeakPtr<> | |
| 313 // is invalidated. | |
| 314 COMPILE_ASSERT(is_void<ReturnType>::value, | |
| 315 weak_ptrs_can_only_bind_to_methods_without_return_values); | |
| 316 }; | |
| 317 | |
| 318 #endif | |
| 319 | |
| 320 // Invoker<> | |
| 321 // | |
| 322 // See description at the top of the file. | |
| 323 template <typename BoundIndices, | |
| 324 typename StorageType, typename Unwrappers, | |
| 325 typename InvokeHelperType, typename UnboundForwardRunType> | |
| 326 struct Invoker; | |
| 327 | |
| 328 template <size_t... bound_indices, | |
| 329 typename StorageType, | |
| 330 typename... Unwrappers, | |
| 331 typename InvokeHelperType, | |
| 332 typename R, | |
| 333 typename... UnboundForwardArgs> | |
| 334 struct Invoker<IndexSequence<bound_indices...>, | |
| 335 StorageType, TypeList<Unwrappers...>, | |
| 336 InvokeHelperType, R(UnboundForwardArgs...)> { | |
| 337 static R Run(BindStateBase* base, | |
| 338 UnboundForwardArgs... unbound_args) { | |
| 339 StorageType* storage = static_cast<StorageType*>(base); | |
| 340 // Local references to make debugger stepping easier. If in a debugger, | |
| 341 // you really want to warp ahead and step through the | |
| 342 // InvokeHelper<>::MakeItSo() call below. | |
| 343 return InvokeHelperType::MakeItSo( | |
| 344 storage->runnable_, | |
| 345 Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))..., | |
| 346 CallbackForward(unbound_args)...); | |
| 347 } | |
| 348 }; | |
| 349 | |
| 350 | |
| 351 // BindState<> | |
| 352 // | |
| 353 // This stores all the state passed into Bind() and is also where most | |
| 354 // of the template resolution magic occurs. | |
| 355 // | |
| 356 // Runnable is the functor we are binding arguments to. | |
| 357 // RunType is type of the Run() function that the Invoker<> should use. | |
| 358 // Normally, this is the same as the RunType of the Runnable, but it can | |
| 359 // be different if an adapter like IgnoreResult() has been used. | |
| 360 // | |
| 361 // BoundArgsType contains the storage type for all the bound arguments by | |
| 362 // (ab)using a function type. | |
| 363 template <typename Runnable, typename RunType, typename BoundArgList> | |
| 364 struct BindState; | |
| 365 | |
| 366 template <typename Runnable, | |
| 367 typename R, | |
| 368 typename... Args, | |
| 369 typename... BoundArgs> | |
| 370 struct BindState<Runnable, R(Args...), TypeList<BoundArgs...>> final | |
| 371 : public BindStateBase { | |
| 372 private: | |
| 373 using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>; | |
| 374 using RunnableType = Runnable; | |
| 375 | |
| 376 // true_type if Runnable is a method invocation and the first bound argument | |
| 377 // is a WeakPtr. | |
| 378 using IsWeakCall = | |
| 379 IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>; | |
| 380 | |
| 381 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; | |
| 382 using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>; | |
| 383 using UnboundForwardArgs = DropTypeListItem< | |
| 384 sizeof...(BoundArgs), | |
| 385 TypeList<typename CallbackParamTraits<Args>::ForwardType...>>; | |
| 386 using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>; | |
| 387 | |
| 388 using InvokeHelperArgs = ConcatTypeLists< | |
| 389 TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>, | |
| 390 UnboundForwardArgs>; | |
| 391 using InvokeHelperType = | |
| 392 InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>; | |
| 393 | |
| 394 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; | |
| 395 | |
| 396 public: | |
| 397 using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers, | |
| 398 InvokeHelperType, UnboundForwardRunType>; | |
| 399 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; | |
| 400 | |
| 401 BindState(const Runnable& runnable, const BoundArgs&... bound_args) | |
| 402 : BindStateBase(&Destroy), | |
| 403 runnable_(runnable), | |
| 404 ref_(bound_args...), | |
| 405 bound_args_(bound_args...) {} | |
| 406 | |
| 407 RunnableType runnable_; | |
| 408 MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_; | |
| 409 Tuple<BoundArgs...> bound_args_; | |
| 410 | |
| 411 private: | |
| 412 ~BindState() {} | |
| 413 | |
| 414 static void Destroy(BindStateBase* self) { | |
| 415 delete static_cast<BindState*>(self); | |
| 416 } | |
| 417 }; | |
| 418 | |
| 419 } // namespace internal | |
| 420 } // namespace base | |
| 421 | |
| 422 #endif // BASE_BIND_INTERNAL_H_ | |
| OLD | NEW |