|  | $$ This is a pump file for generating file templates.  Pump is a python | 
|  | $$ script that is part of the Google Test suite of utilities.  Description | 
|  | $$ can be found here: | 
|  | $$ | 
|  | $$ http://code.google.com/p/googletest/wiki/PumpManual | 
|  | $$ | 
|  |  | 
|  | $$ | 
|  | $$ MAX_ARITY controls the number of arguments that Bind() supports. | 
|  | $$ The amount of code, and more importantly, the number of template types | 
|  | $$ generated by pump grows at O(MAX_ARITY^2). | 
|  | $$ | 
|  | $$ We tried going to 11 and found it imposed an extra 10 penalty on windows | 
|  | $$ cycle times compared to our original baseline of 6. | 
|  | $$ | 
|  | $$ Currently 7 is chosen as a compromise between supporting a convenient | 
|  | $$ number of arguments and keeping compile times low.  At 7, we have 115 | 
|  | $$ templates being generated by pump. | 
|  | $$ | 
|  | $$ Be careful when adjusting this number.  If people find a need to bind | 
|  | $$ a larger number of arguments, consider refactoring the function to use | 
|  | $$ a param struct instead of raising the MAX_ARITY. | 
|  | $$ | 
|  | $$ See http://crbug.com/98542 for more context. | 
|  | $$ | 
|  | $var MAX_ARITY = 7 | 
|  |  | 
|  | // 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" | 
|  | #include "base/callback_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 COMPILE_ASSERT asserts 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 { | 
|  |  | 
|  | $range ARITY 0..MAX_ARITY | 
|  | $for ARITY [[ | 
|  | $range ARG 1..ARITY | 
|  |  | 
|  | template <typename Functor[[]] | 
|  | $if ARITY > 0 [[, ]] $for ARG , [[typename P$(ARG)]]> | 
|  | base::Callback< | 
|  | typename internal::BindState< | 
|  | typename internal::FunctorTraits<Functor>::RunnableType, | 
|  | typename internal::FunctorTraits<Functor>::RunType, | 
|  | void($for ARG , [[typename internal::CallbackParamTraits<P$(ARG)>::StorageType]])> | 
|  | ::UnboundRunType> | 
|  | Bind(Functor functor | 
|  | $if ARITY > 0 [[, ]] $for ARG , [[const P$(ARG)& p$(ARG)]]) { | 
|  | // Typedefs for how to store and run the functor. | 
|  | typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType; | 
|  | typedef typename internal::FunctorTraits<Functor>::RunType RunType; | 
|  |  | 
|  | $if ARITY > 0 [[ | 
|  |  | 
|  | // Use RunnableType::RunType instead of RunType above because our | 
|  | // checks should below for bound references need to know what the actual | 
|  | // functor is going to interpret the argument as. | 
|  | typedef internal::FunctionTraits<typename RunnableType::RunType> | 
|  | BoundFunctorTraits; | 
|  |  | 
|  | // 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. | 
|  | COMPILE_ASSERT( | 
|  | !($for ARG || [[ | 
|  | is_non_const_reference<typename BoundFunctorTraits::A$(ARG)Type>::value ]]), | 
|  | do_not_bind_functions_with_nonconst_ref); | 
|  |  | 
|  | ]] | 
|  |  | 
|  |  | 
|  | $for ARG [[ | 
|  |  | 
|  |  | 
|  | $if ARG == 1 [[ | 
|  | // 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. | 
|  | COMPILE_ASSERT( | 
|  | internal::HasIsMethodTag<RunnableType>::value || | 
|  | !internal::NeedsScopedRefptrButGetsRawPtr<P$(ARG)>::value, | 
|  | p$(ARG)_is_refcounted_type_and_needs_scoped_refptr); | 
|  | COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value || | 
|  | !is_array<P$(ARG)>::value, | 
|  | first_bound_argument_to_method_cannot_be_array); | 
|  | ]] $else [[ | 
|  | COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P$(ARG)>::value, | 
|  | p$(ARG)_is_refcounted_type_and_needs_scoped_refptr); | 
|  | ]]  $$ $if ARG | 
|  |  | 
|  | ]]  $$ $for ARG | 
|  |  | 
|  | typedef internal::BindState<RunnableType, RunType, [[]] | 
|  | void($for ARG , [[typename internal::CallbackParamTraits<P$(ARG)>::StorageType]])> [[]] | 
|  | BindState; | 
|  |  | 
|  |  | 
|  | return Callback<typename BindState::UnboundRunType>( | 
|  | new BindState(internal::MakeRunnable(functor)[[]] | 
|  | $if ARITY > 0 [[, ]] $for ARG , [[p$(ARG)]])); | 
|  | } | 
|  |  | 
|  | ]]  $$ for ARITY | 
|  |  | 
|  | }  // namespace base | 
|  |  | 
|  | #endif  // BASE_BIND_H_ |