| // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BASE_BIND_H_ | 
 | #define BASE_BIND_H_ | 
 |  | 
 | #include "base/bind_internal.h" | 
 |  | 
 | // ----------------------------------------------------------------------------- | 
 | // Usage documentation | 
 | // ----------------------------------------------------------------------------- | 
 | // | 
 | // See base/callback.h for documentation. | 
 | // | 
 | // | 
 | // ----------------------------------------------------------------------------- | 
 | // Implementation notes | 
 | // ----------------------------------------------------------------------------- | 
 | // | 
 | // If you're reading the implementation, before proceeding further, you should | 
 | // read the top comment of base/bind_internal.h for a definition of common | 
 | // terms and concepts. | 
 | // | 
 | // RETURN TYPES | 
 | // | 
 | // Though Bind()'s result is meant to be stored in a Callback<> type, it | 
 | // cannot actually return the exact type without requiring a large amount | 
 | // of extra template specializations. The problem is that in order to | 
 | // discern the correct specialization of Callback<>, Bind would need to | 
 | // unwrap the function signature to determine the signature's arity, and | 
 | // whether or not it is a method. | 
 | // | 
 | // Each unique combination of (arity, function_type, num_prebound) where | 
 | // function_type is one of {function, method, const_method} would require | 
 | // one specialization.  We eventually have to do a similar number of | 
 | // specializations anyways in the implementation (see the Invoker<>, | 
 | // classes).  However, it is avoidable in Bind if we return the result | 
 | // via an indirection like we do below. | 
 | // | 
 | // TODO(ajwong): We might be able to avoid this now, but need to test. | 
 | // | 
 | // It is possible to move most of the static_assert into BindState<>, but it | 
 | // feels a little nicer to have the asserts here so people do not need to crack | 
 | // open bind_internal.h.  On the other hand, it makes Bind() harder to read. | 
 |  | 
 | namespace base { | 
 |  | 
 | namespace internal { | 
 |  | 
 | // Don't use Alias Template directly here to avoid a compile error on MSVC2013. | 
 | template <typename Functor, typename... Args> | 
 | struct MakeUnboundRunTypeImpl { | 
 |   using Type = | 
 |       typename BindState< | 
 |           typename FunctorTraits<Functor>::RunnableType, | 
 |           typename FunctorTraits<Functor>::RunType, | 
 |           Args...>::UnboundRunType; | 
 | }; | 
 |  | 
 | }  // namespace internal | 
 |  | 
 | template <typename Functor, typename... Args> | 
 | using MakeUnboundRunType = | 
 |     typename internal::MakeUnboundRunTypeImpl<Functor, Args...>::Type; | 
 |  | 
 | template <typename Functor, typename... Args> | 
 | base::Callback<MakeUnboundRunType<Functor, Args...>> | 
 | Bind(Functor functor, Args&&... args) { | 
 |   // Type aliases for how to store and run the functor. | 
 |   using RunnableType = typename internal::FunctorTraits<Functor>::RunnableType; | 
 |   using RunType = typename internal::FunctorTraits<Functor>::RunType; | 
 |  | 
 |   // Use RunnableType::RunType instead of RunType above because our | 
 |   // checks below for bound references need to know what the actual | 
 |   // functor is going to interpret the argument as. | 
 |   using BoundRunType = typename RunnableType::RunType; | 
 |  | 
 |   using BoundArgs = | 
 |       internal::TakeTypeListItem<sizeof...(Args), | 
 |                                  internal::ExtractArgs<BoundRunType>>; | 
 |  | 
 |   // Do not allow binding a non-const reference parameter. Non-const reference | 
 |   // parameters are disallowed by the Google style guide.  Also, binding a | 
 |   // non-const reference parameter can make for subtle bugs because the | 
 |   // invoked function will receive a reference to the stored copy of the | 
 |   // argument and not the original. | 
 |   static_assert(!internal::HasNonConstReferenceItem<BoundArgs>::value, | 
 |                 "do not bind functions with nonconst ref"); | 
 |  | 
 |   const bool is_method = internal::HasIsMethodTag<RunnableType>::value; | 
 |  | 
 |   // For methods, we need to be careful for parameter 1.  We do not require | 
 |   // a scoped_refptr because BindState<> itself takes care of AddRef() for | 
 |   // methods. We also disallow binding of an array as the method's target | 
 |   // object. | 
 |   static_assert(!internal::BindsArrayToFirstArg<is_method, Args...>::value, | 
 |                 "first bound argument to method cannot be array"); | 
 |   static_assert( | 
 |       !internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value, | 
 |       "a parameter is a refcounted type and needs scoped_refptr"); | 
 |  | 
 |   using BindState = internal::BindState<RunnableType, RunType, Args...>; | 
 |  | 
 |   return Callback<typename BindState::UnboundRunType>( | 
 |       new BindState(internal::MakeRunnable(functor), | 
 |                     std::forward<Args>(args)...)); | 
 | } | 
 |  | 
 | }  // namespace base | 
 |  | 
 | #endif  // BASE_BIND_H_ |