Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: base/bind_internal.h

Issue 2034633002: Decouple Invoker from BindState (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more inline Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_BIND_INTERNAL_H_ 5 #ifndef BASE_BIND_INTERNAL_H_
6 #define BASE_BIND_INTERNAL_H_ 6 #define BASE_BIND_INTERNAL_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <type_traits> 10 #include <type_traits>
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 // from the invocation call. 292 // from the invocation call.
293 // 293 //
294 // WeakCalls similarly need special syntax that is applied to the first 294 // WeakCalls similarly need special syntax that is applied to the first
295 // argument to check if they should no-op themselves. 295 // argument to check if they should no-op themselves.
296 template <bool is_weak_call, typename ReturnType> 296 template <bool is_weak_call, typename ReturnType>
297 struct InvokeHelper; 297 struct InvokeHelper;
298 298
299 template <typename ReturnType> 299 template <typename ReturnType>
300 struct InvokeHelper<false, ReturnType> { 300 struct InvokeHelper<false, ReturnType> {
301 template <typename Runnable, typename... RunArgs> 301 template <typename Runnable, typename... RunArgs>
302 static ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { 302 static inline ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) {
Nico 2016/06/02 17:27:44 "static inline" here makes more sense to me, as it
tzik 2016/06/02 19:09:06 I thought so too. I don't understand why these inl
303 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); 303 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...);
304 } 304 }
305 }; 305 };
306 306
307 template <> 307 template <>
308 struct InvokeHelper<false, void> { 308 struct InvokeHelper<false, void> {
309 template <typename Runnable, typename... RunArgs> 309 template <typename Runnable, typename... RunArgs>
310 static void MakeItSo(Runnable&& runnable, RunArgs&&... args) { 310 static inline void MakeItSo(Runnable&& runnable, RunArgs&&... args) {
311 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); 311 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...);
312 } 312 }
313 }; 313 };
314 314
315 template <> 315 template <>
316 struct InvokeHelper<true, void> { 316 struct InvokeHelper<true, void> {
317 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs> 317 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs>
318 static void MakeItSo(Runnable&& runnable, 318 static inline void MakeItSo(Runnable&& runnable,
319 BoundWeakPtr weak_ptr, 319 BoundWeakPtr weak_ptr,
320 RunArgs&&... args) { 320 RunArgs&&... args) {
321 if (!weak_ptr.get()) { 321 if (!weak_ptr.get()) {
322 return; 322 return;
323 } 323 }
324 std::forward<Runnable>(runnable).Run( 324 std::forward<Runnable>(runnable).Run(
325 weak_ptr.get(), std::forward<RunArgs>(args)...); 325 weak_ptr.get(), std::forward<RunArgs>(args)...);
326 } 326 }
327 }; 327 };
328 328
329 #if !defined(_MSC_VER) 329 #if !defined(_MSC_VER)
330 330
331 template <typename ReturnType> 331 template <typename ReturnType>
332 struct InvokeHelper<true, ReturnType> { 332 struct InvokeHelper<true, ReturnType> {
333 // WeakCalls are only supported for functions with a void return type. 333 // WeakCalls are only supported for functions with a void return type.
334 // Otherwise, the function result would be undefined if the the WeakPtr<> 334 // Otherwise, the function result would be undefined if the the WeakPtr<>
335 // is invalidated. 335 // is invalidated.
336 static_assert(std::is_void<ReturnType>::value, 336 static_assert(std::is_void<ReturnType>::value,
337 "weak_ptrs can only bind to methods without return values"); 337 "weak_ptrs can only bind to methods without return values");
338 }; 338 };
339 339
340 #endif 340 #endif
341 341
342 // Invoker<> 342 // Invoker<>
343 // 343 //
344 // See description at the top of the file. 344 // See description at the top of the file.
345 template <typename BoundIndices, typename StorageType, 345 template <typename StorageType, typename UnboundRunType>
346 bool is_weak_call, typename UnboundForwardRunType>
347 struct Invoker; 346 struct Invoker;
348 347
349 template <size_t... bound_indices, 348 template <typename StorageType, typename R, typename... UnboundArgs>
350 typename StorageType, 349 struct Invoker<StorageType, R(UnboundArgs...)> {
351 bool is_weak_call,
352 typename R,
353 typename... UnboundArgs>
354 struct Invoker<IndexSequence<bound_indices...>,
355 StorageType,
356 is_weak_call,
357 R(UnboundArgs...)> {
358 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { 350 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) {
359 StorageType* storage = static_cast<StorageType*>(base);
360 // Local references to make debugger stepping easier. If in a debugger, 351 // Local references to make debugger stepping easier. If in a debugger,
361 // you really want to warp ahead and step through the 352 // you really want to warp ahead and step through the
362 // InvokeHelper<>::MakeItSo() call below. 353 // InvokeHelper<>::MakeItSo() call below.
354 StorageType* storage = static_cast<StorageType*>(base);
355 constexpr size_t num_bound_args =
356 std::tuple_size<decltype(storage->bound_args_)>::value;
357 return RunImpl(storage->runnable_,
358 storage->bound_args_,
359 MakeIndexSequence<num_bound_args>(),
360 std::forward<UnboundArgs>(unbound_args)...);
361 }
362
363 template <typename Runnable, typename BoundArgsTuple, size_t... indices>
364 static R inline RunImpl(Runnable&& runnable,
365 BoundArgsTuple&& bound,
366 IndexSequence<indices...>,
367 UnboundArgs&&... unbound_args) {
368 constexpr bool is_method =
369 HasIsMethodTag<typename std::decay<Runnable>::type>::value;
370 constexpr bool is_weak_call =
371 IsWeakMethod<is_method,
372 typename std::decay<BoundArgsTuple>::type>::value;
373
363 return InvokeHelper<is_weak_call, R>::MakeItSo( 374 return InvokeHelper<is_weak_call, R>::MakeItSo(
364 storage->runnable_, Unwrap(get<bound_indices>(storage->bound_args_))..., 375 std::forward<Runnable>(runnable),
376 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
365 std::forward<UnboundArgs>(unbound_args)...); 377 std::forward<UnboundArgs>(unbound_args)...);
366 } 378 }
367 }; 379 };
368 380
369 // Used to implement MakeArgsStorage. 381 // Used to implement MakeArgsStorage.
370 template <bool is_method, typename... BoundArgs> 382 template <bool is_method, typename... BoundArgs>
371 struct MakeArgsStorageImpl { 383 struct MakeArgsStorageImpl {
372 using Type = std::tuple<BoundArgs...>; 384 using Type = std::tuple<BoundArgs...>;
373 }; 385 };
374 386
375 template <typename Obj, typename... BoundArgs> 387 template <typename Obj, typename... BoundArgs>
376 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> { 388 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> {
377 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>; 389 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>;
378 }; 390 };
379 391
380 // Constructs a tuple type to store BoundArgs into BindState. 392 // Constructs a tuple type to store BoundArgs into BindState.
381 // This wraps the first argument into a scoped_refptr if |is_method| is true and 393 // This wraps the first argument into a scoped_refptr if |is_method| is true and
382 // the first argument is a raw pointer. 394 // the first argument is a raw pointer.
383 // Other arguments are adjusted for store and packed into a tuple. 395 // Other arguments are adjusted for store and packed into a tuple.
384 template <bool is_method, typename... BoundArgs> 396 template <bool is_method, typename... BoundArgs>
385 using MakeArgsStorage = typename MakeArgsStorageImpl< 397 using MakeArgsStorage = typename MakeArgsStorageImpl<
386 is_method, typename std::decay<BoundArgs>::type...>::Type; 398 is_method, typename std::decay<BoundArgs>::type...>::Type;
387 399
400 // Used to implement MakeUnboundRunType.
401 template <typename Functor, typename... BoundArgs>
402 struct MakeUnboundRunTypeImpl {
403 using RunType = typename FunctorTraits<Functor>::RunType;
404 using ReturnType = ExtractReturnType<RunType>;
405 using Args = ExtractArgs<RunType>;
406 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>;
407 using Type = MakeFunctionType<ReturnType, UnboundArgs>;
408 };
409
410 // Returns a RunType of bound functor.
411 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
412 template <typename Functor, typename... BoundArgs>
413 using MakeUnboundRunType =
414 typename MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type;
415
388 // BindState<> 416 // BindState<>
389 // 417 //
390 // This stores all the state passed into Bind() and is also where most 418 // This stores all the state passed into Bind() and is also where most
391 // of the template resolution magic occurs. 419 // of the template resolution magic occurs.
392 // 420 //
393 // Runnable is the functor we are binding arguments to. 421 // Runnable is the functor we are binding arguments to.
394 // RunType is type of the Run() function that the Invoker<> should use.
395 // Normally, this is the same as the RunType of the Runnable, but it can
396 // be different if an adapter like IgnoreResult() has been used.
397 // 422 //
398 // BoundArgs contains the storage type for all the bound arguments. 423 // BoundArgs contains the storage type for all the bound arguments.
399 template <typename Runnable, typename RunType, typename... BoundArgs> 424 template <typename Runnable, typename... BoundArgs>
400 struct BindState; 425 struct BindState final : public BindStateBase {
401
402 template <typename Runnable,
403 typename R,
404 typename... Args,
405 typename... BoundArgs>
406 struct BindState<Runnable, R(Args...), BoundArgs...> final
407 : public BindStateBase {
408 private: 426 private:
409 using StorageType = BindState<Runnable, R(Args...), BoundArgs...>;
410 using RunnableType = typename std::decay<Runnable>::type; 427 using RunnableType = typename std::decay<Runnable>::type;
411 428
412 enum { is_method = HasIsMethodTag<RunnableType>::value }; 429 static constexpr bool is_method = HasIsMethodTag<RunnableType>::value;
413 enum { is_weak_call = IsWeakMethod<
414 is_method, typename std::decay<BoundArgs>::type...>::value};
415
416 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>;
417 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>;
418 430
419 public: 431 public:
420 using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
421 using InvokerType =
422 Invoker<BoundIndices, StorageType, is_weak_call, UnboundRunType>;
423
424 template <typename... ForwardArgs> 432 template <typename... ForwardArgs>
425 BindState(RunnableType runnable, ForwardArgs&&... bound_args) 433 explicit BindState(RunnableType runnable, ForwardArgs&&... bound_args)
426 : BindStateBase(&Destroy), 434 : BindStateBase(&Destroy),
427 runnable_(std::move(runnable)), 435 runnable_(std::move(runnable)),
428 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} 436 bound_args_(std::forward<ForwardArgs>(bound_args)...) {}
429 437
430 RunnableType runnable_; 438 RunnableType runnable_;
431 MakeArgsStorage<is_method, BoundArgs...> bound_args_; 439 MakeArgsStorage<is_method, BoundArgs...> bound_args_;
432 440
433 private: 441 private:
434 ~BindState() {} 442 ~BindState() {}
435 443
436 static void Destroy(BindStateBase* self) { 444 static void Destroy(BindStateBase* self) {
437 delete static_cast<BindState*>(self); 445 delete static_cast<BindState*>(self);
438 } 446 }
439 }; 447 };
440 448
441 } // namespace internal 449 } // namespace internal
442 } // namespace base 450 } // namespace base
443 451
444 #endif // BASE_BIND_INTERNAL_H_ 452 #endif // BASE_BIND_INTERNAL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698