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

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: remove base::internal::MakeUnboundRunType Created 4 years, 5 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
« no previous file with comments | « base/bind_helpers.h ('k') | base/callback.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <tuple> 10 #include <tuple>
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 // from the invocation call. 293 // from the invocation call.
294 // 294 //
295 // WeakCalls similarly need special syntax that is applied to the first 295 // WeakCalls similarly need special syntax that is applied to the first
296 // argument to check if they should no-op themselves. 296 // argument to check if they should no-op themselves.
297 template <bool is_weak_call, typename ReturnType> 297 template <bool is_weak_call, typename ReturnType>
298 struct InvokeHelper; 298 struct InvokeHelper;
299 299
300 template <typename ReturnType> 300 template <typename ReturnType>
301 struct InvokeHelper<false, ReturnType> { 301 struct InvokeHelper<false, ReturnType> {
302 template <typename Runnable, typename... RunArgs> 302 template <typename Runnable, typename... RunArgs>
303 static ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) { 303 static inline ReturnType MakeItSo(Runnable&& runnable, RunArgs&&... args) {
304 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); 304 return std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...);
305 } 305 }
306 }; 306 };
307 307
308 template <> 308 template <>
309 struct InvokeHelper<false, void> { 309 struct InvokeHelper<false, void> {
310 template <typename Runnable, typename... RunArgs> 310 template <typename Runnable, typename... RunArgs>
311 static void MakeItSo(Runnable&& runnable, RunArgs&&... args) { 311 static inline void MakeItSo(Runnable&& runnable, RunArgs&&... args) {
312 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...); 312 std::forward<Runnable>(runnable).Run(std::forward<RunArgs>(args)...);
313 } 313 }
314 }; 314 };
315 315
316 template <> 316 template <>
317 struct InvokeHelper<true, void> { 317 struct InvokeHelper<true, void> {
318 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs> 318 template <typename Runnable, typename BoundWeakPtr, typename... RunArgs>
319 static void MakeItSo(Runnable&& runnable, 319 static void MakeItSo(Runnable&& runnable,
320 BoundWeakPtr&& weak_ptr, 320 BoundWeakPtr&& weak_ptr,
321 RunArgs&&... args) { 321 RunArgs&&... args) {
(...skipping 14 matching lines...) Expand all
336 // is invalidated. 336 // is invalidated.
337 static_assert(std::is_void<ReturnType>::value, 337 static_assert(std::is_void<ReturnType>::value,
338 "weak_ptrs can only bind to methods without return values"); 338 "weak_ptrs can only bind to methods without return values");
339 }; 339 };
340 340
341 #endif 341 #endif
342 342
343 // Invoker<> 343 // Invoker<>
344 // 344 //
345 // See description at the top of the file. 345 // See description at the top of the file.
346 template <typename BoundIndices, typename StorageType, 346 template <typename StorageType, typename UnboundRunType>
347 bool is_weak_call, typename UnboundForwardRunType>
348 struct Invoker; 347 struct Invoker;
349 348
350 template <size_t... bound_indices, 349 template <typename StorageType, typename R, typename... UnboundArgs>
351 typename StorageType, 350 struct Invoker<StorageType, R(UnboundArgs...)> {
352 bool is_weak_call,
353 typename R,
354 typename... UnboundArgs>
355 struct Invoker<IndexSequence<bound_indices...>,
356 StorageType,
357 is_weak_call,
358 R(UnboundArgs...)> {
359 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) { 351 static R Run(BindStateBase* base, UnboundArgs&&... unbound_args) {
360 const StorageType* storage = static_cast<StorageType*>(base);
361 // Local references to make debugger stepping easier. If in a debugger, 352 // Local references to make debugger stepping easier. If in a debugger,
362 // you really want to warp ahead and step through the 353 // you really want to warp ahead and step through the
363 // InvokeHelper<>::MakeItSo() call below. 354 // InvokeHelper<>::MakeItSo() call below.
355 const StorageType* storage = static_cast<StorageType*>(base);
356 static constexpr size_t num_bound_args =
357 std::tuple_size<decltype(storage->bound_args_)>::value;
358 return RunImpl(storage->runnable_,
359 storage->bound_args_,
360 MakeIndexSequence<num_bound_args>(),
361 std::forward<UnboundArgs>(unbound_args)...);
362 }
363
364 template <typename Runnable, typename BoundArgsTuple, size_t... indices>
365 static inline R RunImpl(Runnable&& runnable,
366 BoundArgsTuple&& bound,
367 IndexSequence<indices...>,
368 UnboundArgs&&... unbound_args) {
369 static constexpr bool is_method =
370 HasIsMethodTag<typename std::decay<Runnable>::type>::value;
371
372 using DecayedArgsTuple = typename std::decay<BoundArgsTuple>::type;
373 static constexpr bool is_weak_call =
374 IsWeakMethod<is_method,
375 typename std::tuple_element<
376 indices,
377 DecayedArgsTuple>::type...>::value;
378
364 return InvokeHelper<is_weak_call, R>::MakeItSo( 379 return InvokeHelper<is_weak_call, R>::MakeItSo(
365 storage->runnable_, 380 std::forward<Runnable>(runnable),
366 Unwrap(std::get<bound_indices>(storage->bound_args_))..., 381 Unwrap(std::get<indices>(std::forward<BoundArgsTuple>(bound)))...,
367 std::forward<UnboundArgs>(unbound_args)...); 382 std::forward<UnboundArgs>(unbound_args)...);
368 } 383 }
369 }; 384 };
370 385
371 // Used to implement MakeArgsStorage. 386 // Used to implement MakeArgsStorage.
372 template <bool is_method, typename... BoundArgs> 387 template <bool is_method, typename... BoundArgs>
373 struct MakeArgsStorageImpl { 388 struct MakeArgsStorageImpl {
374 using Type = std::tuple<BoundArgs...>; 389 using Type = std::tuple<BoundArgs...>;
375 }; 390 };
376 391
377 template <typename Obj, typename... BoundArgs> 392 template <typename Obj, typename... BoundArgs>
378 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> { 393 struct MakeArgsStorageImpl<true, Obj*, BoundArgs...> {
379 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>; 394 using Type = std::tuple<scoped_refptr<Obj>, BoundArgs...>;
380 }; 395 };
381 396
382 // Constructs a tuple type to store BoundArgs into BindState. 397 // Constructs a tuple type to store BoundArgs into BindState.
383 // This wraps the first argument into a scoped_refptr if |is_method| is true and 398 // This wraps the first argument into a scoped_refptr if |is_method| is true and
384 // the first argument is a raw pointer. 399 // the first argument is a raw pointer.
385 // Other arguments are adjusted for store and packed into a tuple. 400 // Other arguments are adjusted for store and packed into a tuple.
386 template <bool is_method, typename... BoundArgs> 401 template <bool is_method, typename... BoundArgs>
387 using MakeArgsStorage = typename MakeArgsStorageImpl< 402 using MakeArgsStorage = typename MakeArgsStorageImpl<
388 is_method, typename std::decay<BoundArgs>::type...>::Type; 403 is_method, typename std::decay<BoundArgs>::type...>::Type;
389 404
405 // Used to implement MakeUnboundRunType.
406 template <typename Functor, typename... BoundArgs>
407 struct MakeUnboundRunTypeImpl {
408 using RunType = typename FunctorTraits<Functor>::RunType;
409 using ReturnType = ExtractReturnType<RunType>;
410 using Args = ExtractArgs<RunType>;
411 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>;
412 using Type = MakeFunctionType<ReturnType, UnboundArgs>;
413 };
414
390 // BindState<> 415 // BindState<>
391 // 416 //
392 // This stores all the state passed into Bind() and is also where most 417 // This stores all the state passed into Bind() and is also where most
393 // of the template resolution magic occurs. 418 // of the template resolution magic occurs.
394 // 419 //
395 // Runnable is the functor we are binding arguments to. 420 // Runnable is the functor we are binding arguments to.
396 // RunType is type of the Run() function that the Invoker<> should use.
397 // Normally, this is the same as the RunType of the Runnable, but it can
398 // be different if an adapter like IgnoreResult() has been used.
399 // 421 //
400 // BoundArgs contains the storage type for all the bound arguments. 422 // BoundArgs contains the storage type for all the bound arguments.
401 template <typename Runnable, typename RunType, typename... BoundArgs> 423 template <typename Runnable, typename... BoundArgs>
402 struct BindState; 424 struct BindState final : public BindStateBase {
403
404 template <typename Runnable,
405 typename R,
406 typename... Args,
407 typename... BoundArgs>
408 struct BindState<Runnable, R(Args...), BoundArgs...> final
409 : public BindStateBase {
410 private: 425 private:
411 using StorageType = BindState<Runnable, R(Args...), BoundArgs...>;
412 using RunnableType = typename std::decay<Runnable>::type; 426 using RunnableType = typename std::decay<Runnable>::type;
413 427
414 enum { is_method = HasIsMethodTag<RunnableType>::value }; 428 static constexpr bool is_method = HasIsMethodTag<RunnableType>::value;
415 enum { is_weak_call = IsWeakMethod<
416 is_method, typename std::decay<BoundArgs>::type...>::value};
417
418 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>;
419 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>;
420 429
421 public: 430 public:
422 using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
423 using InvokerType =
424 Invoker<BoundIndices, StorageType, is_weak_call, UnboundRunType>;
425
426 template <typename... ForwardArgs> 431 template <typename... ForwardArgs>
427 BindState(RunnableType runnable, ForwardArgs&&... bound_args) 432 explicit BindState(RunnableType runnable, ForwardArgs&&... bound_args)
428 : BindStateBase(&Destroy), 433 : BindStateBase(&Destroy),
429 runnable_(std::move(runnable)), 434 runnable_(std::move(runnable)),
430 bound_args_(std::forward<ForwardArgs>(bound_args)...) {} 435 bound_args_(std::forward<ForwardArgs>(bound_args)...) {}
431 436
432 RunnableType runnable_; 437 RunnableType runnable_;
433 MakeArgsStorage<is_method, BoundArgs...> bound_args_; 438 MakeArgsStorage<is_method, BoundArgs...> bound_args_;
434 439
435 private: 440 private:
436 ~BindState() {} 441 ~BindState() {}
437 442
438 static void Destroy(BindStateBase* self) { 443 static void Destroy(BindStateBase* self) {
439 delete static_cast<BindState*>(self); 444 delete static_cast<BindState*>(self);
440 } 445 }
441 }; 446 };
442 447
443 } // namespace internal 448 } // namespace internal
449
450 // Returns a RunType of bound functor.
451 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
452 template <typename Functor, typename... BoundArgs>
453 using MakeUnboundRunType =
454 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type;
455
444 } // namespace base 456 } // namespace base
445 457
446 #endif // BASE_BIND_INTERNAL_H_ 458 #endif // BASE_BIND_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/bind_helpers.h ('k') | base/callback.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698