Home | History | Annotate | Download | only in base
      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_H_
      6 #define BASE_BIND_H_
      7 
      8 #include "base/bind_internal.h"
      9 
     10 // -----------------------------------------------------------------------------
     11 // Usage documentation
     12 // -----------------------------------------------------------------------------
     13 //
     14 // See //docs/callback.md for documentation.
     15 //
     16 //
     17 // -----------------------------------------------------------------------------
     18 // Implementation notes
     19 // -----------------------------------------------------------------------------
     20 //
     21 // If you're reading the implementation, before proceeding further, you should
     22 // read the top comment of base/bind_internal.h for a definition of common
     23 // terms and concepts.
     24 
     25 namespace base {
     26 
     27 // Bind as OnceCallback.
     28 template <typename Functor, typename... Args>
     29 inline OnceCallback<MakeUnboundRunType<Functor, Args...>>
     30 BindOnce(Functor&& functor, Args&&... args) {
     31   using BindState = internal::MakeBindStateType<Functor, Args...>;
     32   using UnboundRunType = MakeUnboundRunType<Functor, Args...>;
     33   using Invoker = internal::Invoker<BindState, UnboundRunType>;
     34   using CallbackType = OnceCallback<UnboundRunType>;
     35 
     36   // Store the invoke func into PolymorphicInvoke before casting it to
     37   // InvokeFuncStorage, so that we can ensure its type matches to
     38   // PolymorphicInvoke, to which CallbackType will cast back.
     39   using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke;
     40   PolymorphicInvoke invoke_func = &Invoker::RunOnce;
     41 
     42   using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage;
     43   return CallbackType(new BindState(
     44       reinterpret_cast<InvokeFuncStorage>(invoke_func),
     45       std::forward<Functor>(functor),
     46       std::forward<Args>(args)...));
     47 }
     48 
     49 // Bind as RepeatingCallback.
     50 template <typename Functor, typename... Args>
     51 inline RepeatingCallback<MakeUnboundRunType<Functor, Args...>>
     52 BindRepeating(Functor&& functor, Args&&... args) {
     53   using BindState = internal::MakeBindStateType<Functor, Args...>;
     54   using UnboundRunType = MakeUnboundRunType<Functor, Args...>;
     55   using Invoker = internal::Invoker<BindState, UnboundRunType>;
     56   using CallbackType = RepeatingCallback<UnboundRunType>;
     57 
     58   // Store the invoke func into PolymorphicInvoke before casting it to
     59   // InvokeFuncStorage, so that we can ensure its type matches to
     60   // PolymorphicInvoke, to which CallbackType will cast back.
     61   using PolymorphicInvoke = typename CallbackType::PolymorphicInvoke;
     62   PolymorphicInvoke invoke_func = &Invoker::Run;
     63 
     64   using InvokeFuncStorage = internal::BindStateBase::InvokeFuncStorage;
     65   return CallbackType(new BindState(
     66       reinterpret_cast<InvokeFuncStorage>(invoke_func),
     67       std::forward<Functor>(functor),
     68       std::forward<Args>(args)...));
     69 }
     70 
     71 // Unannotated Bind.
     72 // TODO(tzik): Deprecate this and migrate to OnceCallback and
     73 // RepeatingCallback, once they get ready.
     74 template <typename Functor, typename... Args>
     75 inline Callback<MakeUnboundRunType<Functor, Args...>>
     76 Bind(Functor&& functor, Args&&... args) {
     77   return BindRepeating(std::forward<Functor>(functor),
     78                        std::forward<Args>(args)...);
     79 }
     80 
     81 }  // namespace base
     82 
     83 #endif  // BASE_BIND_H_
     84