15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file was GENERATED by command:
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     pump.py bind.h.pump
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DO NOT EDIT BY HAND!!!
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_BIND_H_
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_BIND_H_
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_internal.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_internal.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Usage documentation
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See base/callback.h for documentation.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation notes
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you're reading the implementation, before proceeding further, you should
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// read the top comment of base/bind_internal.h for a definition of common
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// terms and concepts.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RETURN TYPES
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Though Bind()'s result is meant to be stored in a Callback<> type, it
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cannot actually return the exact type without requiring a large amount
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of extra template specializations. The problem is that in order to
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// discern the correct specialization of Callback<>, Bind would need to
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unwrap the function signature to determine the signature's arity, and
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether or not it is a method.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Each unique combination of (arity, function_type, num_prebound) where
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function_type is one of {function, method, const_method} would require
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one specialization.  We eventually have to do a similar number of
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specializations anyways in the implementation (see the Invoker<>,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// classes).  However, it is avoidable in Bind if we return the result
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// via an indirection like we do below.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(ajwong): We might be able to avoid this now, but need to test.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is possible to move most of the COMPILE_ASSERT asserts into BindState<>,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but it feels a little nicer to have the asserts here so people do not
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to crack open bind_internal.h.  On the other hand, it makes Bind()
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// harder to read.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor>
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void()>
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType, void()> BindState;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor)));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor, typename P1>
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void(typename internal::CallbackParamTraits<P1>::StorageType)>
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor, const P1& p1) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use RunnableType::RunType instead of RunType above because our
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks should below for bound references need to know what the actual
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functor is going to interpret the argument as.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::FunctionTraits<typename RunnableType::RunType>
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundFunctorTraits;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow binding a non-const reference parameter. Non-const reference
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameters are disallowed by the Google style guide.  Also, binding a
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-const reference parameter can make for subtle bugs because the
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked function will receive a reference to the stored copy of the
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument and not the original.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_not_bind_functions_with_nonconst_ref);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For methods, we need to be careful for parameter 1.  We do not require
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a scoped_refptr because BindState<> itself takes care of AddRef() for
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. We also disallow binding of an array as the method's target
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal::HasIsMethodTag<RunnableType>::value ||
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p1_is_refcounted_type_and_needs_scoped_refptr);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     !is_array<P1>::value,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 first_bound_argument_to_method_cannot_be_array);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void(typename internal::CallbackParamTraits<P1>::StorageType)> BindState;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor), p1));
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor, typename P1, typename P2>
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void(typename internal::CallbackParamTraits<P1>::StorageType,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P2>::StorageType)>
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor, const P1& p1, const P2& p2) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use RunnableType::RunType instead of RunType above because our
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks should below for bound references need to know what the actual
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functor is going to interpret the argument as.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::FunctionTraits<typename RunnableType::RunType>
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundFunctorTraits;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow binding a non-const reference parameter. Non-const reference
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameters are disallowed by the Google style guide.  Also, binding a
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-const reference parameter can make for subtle bugs because the
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked function will receive a reference to the stored copy of the
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument and not the original.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_not_bind_functions_with_nonconst_ref);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For methods, we need to be careful for parameter 1.  We do not require
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a scoped_refptr because BindState<> itself takes care of AddRef() for
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. We also disallow binding of an array as the method's target
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal::HasIsMethodTag<RunnableType>::value ||
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p1_is_refcounted_type_and_needs_scoped_refptr);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     !is_array<P1>::value,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 first_bound_argument_to_method_cannot_be_array);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p2_is_refcounted_type_and_needs_scoped_refptr);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void(typename internal::CallbackParamTraits<P1>::StorageType,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P2>::StorageType)> BindState;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor), p1, p2));
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor, typename P1, typename P2, typename P3>
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void(typename internal::CallbackParamTraits<P1>::StorageType,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P2>::StorageType,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P3>::StorageType)>
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use RunnableType::RunType instead of RunType above because our
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks should below for bound references need to know what the actual
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functor is going to interpret the argument as.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::FunctionTraits<typename RunnableType::RunType>
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundFunctorTraits;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow binding a non-const reference parameter. Non-const reference
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameters are disallowed by the Google style guide.  Also, binding a
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-const reference parameter can make for subtle bugs because the
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked function will receive a reference to the stored copy of the
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument and not the original.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ),
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_not_bind_functions_with_nonconst_ref);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For methods, we need to be careful for parameter 1.  We do not require
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a scoped_refptr because BindState<> itself takes care of AddRef() for
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. We also disallow binding of an array as the method's target
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal::HasIsMethodTag<RunnableType>::value ||
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p1_is_refcounted_type_and_needs_scoped_refptr);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     !is_array<P1>::value,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 first_bound_argument_to_method_cannot_be_array);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p2_is_refcounted_type_and_needs_scoped_refptr);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p3_is_refcounted_type_and_needs_scoped_refptr);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void(typename internal::CallbackParamTraits<P1>::StorageType,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P2>::StorageType,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P3>::StorageType)> BindState;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor), p1, p2, p3));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor, typename P1, typename P2, typename P3, typename P4>
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void(typename internal::CallbackParamTraits<P1>::StorageType,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P2>::StorageType,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P3>::StorageType,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P4>::StorageType)>
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use RunnableType::RunType instead of RunType above because our
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks should below for bound references need to know what the actual
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functor is going to interpret the argument as.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::FunctionTraits<typename RunnableType::RunType>
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundFunctorTraits;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow binding a non-const reference parameter. Non-const reference
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameters are disallowed by the Google style guide.  Also, binding a
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-const reference parameter can make for subtle bugs because the
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked function will receive a reference to the stored copy of the
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument and not the original.
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_not_bind_functions_with_nonconst_ref);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For methods, we need to be careful for parameter 1.  We do not require
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a scoped_refptr because BindState<> itself takes care of AddRef() for
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. We also disallow binding of an array as the method's target
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal::HasIsMethodTag<RunnableType>::value ||
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p1_is_refcounted_type_and_needs_scoped_refptr);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     !is_array<P1>::value,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 first_bound_argument_to_method_cannot_be_array);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p2_is_refcounted_type_and_needs_scoped_refptr);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p3_is_refcounted_type_and_needs_scoped_refptr);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p4_is_refcounted_type_and_needs_scoped_refptr);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void(typename internal::CallbackParamTraits<P1>::StorageType,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P2>::StorageType,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P3>::StorageType,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P4>::StorageType)> BindState;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor, typename P1, typename P2, typename P3, typename P4,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename P5>
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void(typename internal::CallbackParamTraits<P1>::StorageType,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P2>::StorageType,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P3>::StorageType,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P4>::StorageType,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P5>::StorageType)>
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const P5& p5) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use RunnableType::RunType instead of RunType above because our
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks should below for bound references need to know what the actual
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functor is going to interpret the argument as.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::FunctionTraits<typename RunnableType::RunType>
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundFunctorTraits;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow binding a non-const reference parameter. Non-const reference
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameters are disallowed by the Google style guide.  Also, binding a
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-const reference parameter can make for subtle bugs because the
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked function will receive a reference to the stored copy of the
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument and not the original.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ),
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_not_bind_functions_with_nonconst_ref);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For methods, we need to be careful for parameter 1.  We do not require
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a scoped_refptr because BindState<> itself takes care of AddRef() for
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. We also disallow binding of an array as the method's target
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal::HasIsMethodTag<RunnableType>::value ||
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p1_is_refcounted_type_and_needs_scoped_refptr);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     !is_array<P1>::value,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 first_bound_argument_to_method_cannot_be_array);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p2_is_refcounted_type_and_needs_scoped_refptr);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p3_is_refcounted_type_and_needs_scoped_refptr);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p4_is_refcounted_type_and_needs_scoped_refptr);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p5_is_refcounted_type_and_needs_scoped_refptr);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void(typename internal::CallbackParamTraits<P1>::StorageType,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P2>::StorageType,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P3>::StorageType,
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P4>::StorageType,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P5>::StorageType)> BindState;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor, typename P1, typename P2, typename P3, typename P4,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename P5, typename P6>
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void(typename internal::CallbackParamTraits<P1>::StorageType,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P2>::StorageType,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P3>::StorageType,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P4>::StorageType,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P5>::StorageType,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P6>::StorageType)>
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const P5& p5, const P6& p6) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use RunnableType::RunType instead of RunType above because our
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks should below for bound references need to know what the actual
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functor is going to interpret the argument as.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::FunctionTraits<typename RunnableType::RunType>
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundFunctorTraits;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow binding a non-const reference parameter. Non-const reference
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameters are disallowed by the Google style guide.  Also, binding a
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-const reference parameter can make for subtle bugs because the
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked function will receive a reference to the stored copy of the
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument and not the original.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ),
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_not_bind_functions_with_nonconst_ref);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For methods, we need to be careful for parameter 1.  We do not require
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a scoped_refptr because BindState<> itself takes care of AddRef() for
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. We also disallow binding of an array as the method's target
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal::HasIsMethodTag<RunnableType>::value ||
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p1_is_refcounted_type_and_needs_scoped_refptr);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     !is_array<P1>::value,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 first_bound_argument_to_method_cannot_be_array);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p2_is_refcounted_type_and_needs_scoped_refptr);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p3_is_refcounted_type_and_needs_scoped_refptr);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p4_is_refcounted_type_and_needs_scoped_refptr);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p5_is_refcounted_type_and_needs_scoped_refptr);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p6_is_refcounted_type_and_needs_scoped_refptr);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType,
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void(typename internal::CallbackParamTraits<P1>::StorageType,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P2>::StorageType,
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P3>::StorageType,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P4>::StorageType,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P5>::StorageType,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P6>::StorageType)> BindState;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6));
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Functor, typename P1, typename P2, typename P3, typename P4,
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename P5, typename P6, typename P7>
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Callback<
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typename internal::BindState<
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunnableType,
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        typename internal::FunctorTraits<Functor>::RunType,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void(typename internal::CallbackParamTraits<P1>::StorageType,
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P2>::StorageType,
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P3>::StorageType,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P4>::StorageType,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P5>::StorageType,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P6>::StorageType,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            typename internal::CallbackParamTraits<P7>::StorageType)>
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ::UnboundRunType>
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bind(Functor functor, const P1& p1, const P2& p2, const P3& p3, const P4& p4,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const P5& p5, const P6& p6, const P7& p7) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Typedefs for how to store and run the functor.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef typename internal::FunctorTraits<Functor>::RunType RunType;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use RunnableType::RunType instead of RunType above because our
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks should below for bound references need to know what the actual
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functor is going to interpret the argument as.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::FunctionTraits<typename RunnableType::RunType>
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BoundFunctorTraits;
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow binding a non-const reference parameter. Non-const reference
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameters are disallowed by the Google style guide.  Also, binding a
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-const reference parameter can make for subtle bugs because the
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked function will receive a reference to the stored copy of the
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // argument and not the original.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !(is_non_const_reference<typename BoundFunctorTraits::A1Type>::value ||
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A2Type>::value ||
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A3Type>::value ||
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A4Type>::value ||
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A5Type>::value ||
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A6Type>::value ||
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          is_non_const_reference<typename BoundFunctorTraits::A7Type>::value ),
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      do_not_bind_functions_with_nonconst_ref);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For methods, we need to be careful for parameter 1.  We do not require
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a scoped_refptr because BindState<> itself takes care of AddRef() for
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // methods. We also disallow binding of an array as the method's target
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // object.
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal::HasIsMethodTag<RunnableType>::value ||
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !internal::NeedsScopedRefptrButGetsRawPtr<P1>::value,
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p1_is_refcounted_type_and_needs_scoped_refptr);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::HasIsMethodTag<RunnableType>::value ||
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     !is_array<P1>::value,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 first_bound_argument_to_method_cannot_be_array);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P2>::value,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p2_is_refcounted_type_and_needs_scoped_refptr);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P3>::value,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p3_is_refcounted_type_and_needs_scoped_refptr);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P4>::value,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p4_is_refcounted_type_and_needs_scoped_refptr);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P5>::value,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p5_is_refcounted_type_and_needs_scoped_refptr);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P6>::value,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p6_is_refcounted_type_and_needs_scoped_refptr);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(!internal::NeedsScopedRefptrButGetsRawPtr<P7>::value,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 p7_is_refcounted_type_and_needs_scoped_refptr);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef internal::BindState<RunnableType, RunType,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void(typename internal::CallbackParamTraits<P1>::StorageType,
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P2>::StorageType,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P3>::StorageType,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P4>::StorageType,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P5>::StorageType,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P6>::StorageType,
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      typename internal::CallbackParamTraits<P7>::StorageType)> BindState;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Callback<typename BindState::UnboundRunType>(
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BindState(internal::MakeRunnable(functor), p1, p2, p3, p4, p5, p6,
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p7));
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_BIND_H_
512