|  | // 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_ |