$$ 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
$$

$$ See comment for MAX_ARITY in base/bind.h.pump.
$var MAX_ARITY = 7
$range ARITY 0..MAX_ARITY

// 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_INTERNAL_H_
#define BASE_BIND_INTERNAL_H_

#include "base/bind_helpers.h"
#include "base/callback_internal.h"
#include "base/memory/raw_scoped_refptr_mismatch_checker.h"
#include "base/memory/weak_ptr.h"
#include "base/template_util.h"
#include "build/build_config.h"

#if defined(OS_WIN)
#include "base/bind_internal_win.h"
#endif

namespace base {
namespace internal {

// See base/callback.h for user documentation.
//
//
// CONCEPTS:
//  Runnable -- A type (really a type class) that has a single Run() method
//              and a RunType typedef that corresponds to the type of Run().
//              A Runnable can declare that it should treated like a method
//              call by including a typedef named IsMethod.  The value of
//              this typedef is NOT inspected, only the existence.  When a
//              Runnable declares itself a method, Bind() will enforce special
//              refcounting + WeakPtr handling semantics for the first
//              parameter which is expected to be an object.
//  Functor -- A copyable type representing something that should be called.
//             All function pointers, Callback<>, and Runnables are functors
//             even if the invocation syntax differs.
//  RunType -- A function type (as opposed to function _pointer_ type) for
//             a Run() function.  Usually just a convenience typedef.
//  (Bound)ArgsType -- A function type that is being (ab)used to store the
//                     types of set of arguments.  The "return" type is always
//                     void here.  We use this hack so that we do not need
//                     a new type name for each arity of type. (eg.,
//                     BindState1, BindState2).  This makes forward
//                     declarations and friending much much easier.
//
// Types:
//  RunnableAdapter<> -- Wraps the various "function" pointer types into an
//                       object that adheres to the Runnable interface.
//                       There are |3*ARITY| RunnableAdapter types.
//  FunctionTraits<> -- Type traits that unwrap a function signature into a
//                      a set of easier to use typedefs.  Used mainly for
//                      compile time asserts.
//                      There are |ARITY| FunctionTraits types.
//  ForceVoidReturn<> -- Helper class for translating function signatures to
//                       equivalent forms with a "void" return type.
//                    There are |ARITY| ForceVoidReturn types.
//  FunctorTraits<> -- Type traits used determine the correct RunType and
//                     RunnableType for a Functor.  This is where function
//                     signature adapters are applied.
//                    There are |ARITY| ForceVoidReturn types.
//  MakeRunnable<> -- Takes a Functor and returns an object in the Runnable
//                    type class that represents the underlying Functor.
//                    There are |O(1)| MakeRunnable types.
//  InvokeHelper<> -- Take a Runnable + arguments and actully invokes it.
//                    Handle the differing syntaxes needed for WeakPtr<> support,
//                    and for ignoring return values.  This is separate from
//                    Invoker to avoid creating multiple version of Invoker<>
//                    which grows at O(n^2) with the arity.
//                    There are |k*ARITY| InvokeHelper types.
//  Invoker<> -- Unwraps the curried parameters and executes the Runnable.
//               There are |(ARITY^2 + ARITY)/2| Invoketypes.
//  BindState<> -- Stores the curried parameters, and is the main entry point
//                 into the Bind() system, doing most of the type resolution.
//                 There are ARITY BindState types.

// RunnableAdapter<>
//
// The RunnableAdapter<> templates provide a uniform interface for invoking
// a function pointer, method pointer, or const method pointer. The adapter
// exposes a Run() method with an appropriate signature. Using this wrapper
// allows for writing code that supports all three pointer types without
// undue repetition.  Without it, a lot of code would need to be repeated 3
// times.
//
// For method pointers and const method pointers the first argument to Run()
// is considered to be the received of the method.  This is similar to STL's
// mem_fun().
//
// This class also exposes a RunType typedef that is the function type of the
// Run() function.
//
// If and only if the wrapper contains a method or const method pointer, an
// IsMethod typedef is exposed.  The existence of this typedef (NOT the value)
// marks that the wrapper should be considered a method wrapper.

template <typename Functor>
class RunnableAdapter;

$for ARITY [[
$range ARG 1..ARITY

// Function: Arity $(ARITY).
template <typename R[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
class RunnableAdapter<R(*)($for ARG , [[A$(ARG)]])> {
 public:
  typedef R (RunType)($for ARG , [[A$(ARG)]]);

  explicit RunnableAdapter(R(*function)($for ARG , [[A$(ARG)]]))
      : function_(function) {
  }

  R Run($for ARG , [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
    return function_($for ARG , [[CallbackForward(a$(ARG))]]);
  }

 private:
  R (*function_)($for ARG , [[A$(ARG)]]);
};

// Method: Arity $(ARITY).
template <typename R, typename T[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
class RunnableAdapter<R(T::*)($for ARG , [[A$(ARG)]])> {
 public:
  typedef R (RunType)(T*[[]]
$if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]);
  typedef true_type IsMethod;

  explicit RunnableAdapter(R(T::*method)($for ARG , [[A$(ARG)]]))
      : method_(method) {
  }

  R Run(T* object[[]]
$if ARITY > 0[[, ]]  $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
    return (object->*method_)($for ARG , [[CallbackForward(a$(ARG))]]);
  }

 private:
  R (T::*method_)($for ARG , [[A$(ARG)]]);
};

// Const Method: Arity $(ARITY).
template <typename R, typename T[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
class RunnableAdapter<R(T::*)($for ARG , [[A$(ARG)]]) const> {
 public:
  typedef R (RunType)(const T*[[]]
$if ARITY > 0[[, ]] $for ARG , [[A$(ARG)]]);
  typedef true_type IsMethod;

  explicit RunnableAdapter(R(T::*method)($for ARG , [[A$(ARG)]]) const)
      : method_(method) {
  }

  R Run(const T* object[[]]
$if ARITY > 0[[, ]]  $for ARG, [[typename CallbackParamTraits<A$(ARG)>::ForwardType a$(ARG)]]) {
    return (object->*method_)($for ARG , [[CallbackForward(a$(ARG))]]);
  }

 private:
  R (T::*method_)($for ARG , [[A$(ARG)]]) const;
};

]]  $$ for ARITY


// FunctionTraits<>
//
// Breaks a function signature apart into typedefs for easier introspection.
template <typename Sig>
struct FunctionTraits;

$for ARITY [[
$range ARG 1..ARITY

template <typename R[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
struct FunctionTraits<R($for ARG , [[A$(ARG)]])> {
  typedef R ReturnType;
$for ARG [[

  typedef A$(ARG) A$(ARG)Type;
]]

};

]]


// ForceVoidReturn<>
//
// Set of templates that support forcing the function return type to void.
template <typename Sig>
struct ForceVoidReturn;

$for ARITY [[
$range ARG 1..ARITY

template <typename R[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename A$(ARG)]]>
struct ForceVoidReturn<R($for ARG , [[A$(ARG)]])> {
  typedef void(RunType)($for ARG , [[A$(ARG)]]);
};

]]  $$ for ARITY


// FunctorTraits<>
//
// See description at top of file.
template <typename T>
struct FunctorTraits {
  typedef RunnableAdapter<T> RunnableType;
  typedef typename RunnableType::RunType RunType;
};

template <typename T>
struct FunctorTraits<IgnoreResultHelper<T> > {
  typedef typename FunctorTraits<T>::RunnableType RunnableType;
  typedef typename ForceVoidReturn<
      typename RunnableType::RunType>::RunType RunType;
};

template <typename T>
struct FunctorTraits<Callback<T> > {
  typedef Callback<T> RunnableType;
  typedef typename Callback<T>::RunType RunType;
};


// MakeRunnable<>
//
// Converts a passed in functor to a RunnableType using type inference.

template <typename T>
typename FunctorTraits<T>::RunnableType MakeRunnable(const T& t) {
  return RunnableAdapter<T>(t);
}

template <typename T>
typename FunctorTraits<T>::RunnableType
MakeRunnable(const IgnoreResultHelper<T>& t) {
  return MakeRunnable(t.functor_);
}

template <typename T>
const typename FunctorTraits<Callback<T> >::RunnableType&
MakeRunnable(const Callback<T>& t) {
  DCHECK(!t.is_null());
  return t;
}


// InvokeHelper<>
//
// There are 3 logical InvokeHelper<> specializations: normal, void-return,
// WeakCalls.
//
// The normal type just calls the underlying runnable.
//
// We need a InvokeHelper to handle void return types in order to support
// IgnoreResult().  Normally, if the Runnable's RunType had a void return,
// the template system would just accept "return functor.Run()" ignoring
// the fact that a void function is being used with return. This piece of
// sugar breaks though when the Runnable's RunType is not void.  Thus, we
// need a partial specialization to change the syntax to drop the "return"
// from the invocation call.
//
// WeakCalls similarly need special syntax that is applied to the first
// argument to check if they should no-op themselves.
template <bool IsWeakCall, typename ReturnType, typename Runnable,
          typename ArgsType>
struct InvokeHelper;

$for ARITY [[
$range ARG 1..ARITY
$range WEAKCALL_ARG 2..ARITY

template <typename ReturnType, typename Runnable[[]]
$if ARITY > 0 [[,]] $for ARG , [[typename A$(ARG)]]>
struct InvokeHelper<false, ReturnType, Runnable,
    void($for ARG , [[A$(ARG)]])>  {
  static ReturnType MakeItSo(Runnable runnable[[]]
$if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) {
    return runnable.Run($for ARG , [[CallbackForward(a$(ARG))]]);
  }
};

template <typename Runnable[[]]
$if ARITY > 0 [[,]] $for ARG , [[typename A$(ARG)]]>
struct InvokeHelper<false, void, Runnable,
    void($for ARG , [[A$(ARG)]])>  {
  static void MakeItSo(Runnable runnable[[]]
$if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) {
    runnable.Run($for ARG , [[CallbackForward(a$(ARG))]]);
  }
};

$if ARITY > 0 [[

template <typename Runnable[[]], typename BoundWeakPtr
$if ARITY > 1[[, ]] $for WEAKCALL_ARG , [[typename A$(WEAKCALL_ARG)]]>
struct InvokeHelper<true, void, Runnable,
    void(BoundWeakPtr
$if ARITY > 1[[, ]] $for WEAKCALL_ARG , [[A$(WEAKCALL_ARG)]])>  {
  static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr
$if ARITY > 1[[, ]] $for WEAKCALL_ARG , [[A$(WEAKCALL_ARG) a$(WEAKCALL_ARG)]]) {
    if (!weak_ptr.get()) {
      return;
    }
    runnable.Run(weak_ptr.get()
$if ARITY > 1[[, ]] $for WEAKCALL_ARG , [[CallbackForward(a$(WEAKCALL_ARG))]]);
  }
};

]]

]] $$ for ARITY

#if !defined(_MSC_VER)

template <typename ReturnType, typename Runnable, typename ArgsType>
struct InvokeHelper<true, ReturnType, Runnable, ArgsType> {
  // WeakCalls are only supported for functions with a void return type.
  // Otherwise, the function result would be undefined if the the WeakPtr<>
  // is invalidated.
  COMPILE_ASSERT(is_void<ReturnType>::value,
                 weak_ptrs_can_only_bind_to_methods_without_return_values);
};

#endif

// Invoker<>
//
// See description at the top of the file.
template <int NumBound, typename Storage, typename RunType>
struct Invoker;

$for ARITY [[

$$ Number of bound arguments.
$range BOUND 0..ARITY
$for BOUND [[

$var UNBOUND = ARITY - BOUND
$range ARG 1..ARITY
$range BOUND_ARG 1..BOUND
$range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY

// Arity $(ARITY) -> $(UNBOUND).
template <typename StorageType, typename R[[]]
$if ARITY > 0 [[,]][[]]
$for ARG , [[typename X$(ARG)]]>
struct Invoker<$(BOUND), StorageType, R($for ARG , [[X$(ARG)]])> {
  typedef R(RunType)(BindStateBase*[[]]
$if UNBOUND != 0 [[, ]]
$for UNBOUND_ARG , [[typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType]]);

  typedef R(UnboundRunType)($for UNBOUND_ARG , [[X$(UNBOUND_ARG)]]);

  static R Run(BindStateBase* base[[]]
$if UNBOUND != 0 [[, ]][[]]
$for UNBOUND_ARG , [[
typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)
]][[]]
) {
    StorageType* storage = static_cast<StorageType*>(base);

    // Local references to make debugger stepping easier. If in a debugger,
    // you really want to warp ahead and step through the
    // InvokeHelper<>::MakeItSo() call below.
$for BOUND_ARG
[[

    typedef typename StorageType::Bound$(BOUND_ARG)UnwrapTraits Bound$(BOUND_ARG)UnwrapTraits;
]]


$for BOUND_ARG
[[

    typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType x$(BOUND_ARG) =
        Bound$(BOUND_ARG)UnwrapTraits::Unwrap(storage->p$(BOUND_ARG)_);
]]

    return InvokeHelper<StorageType::IsWeakCall::value, R,
           typename StorageType::RunnableType,
           void(
$for BOUND_ARG , [[
typename Bound$(BOUND_ARG)UnwrapTraits::ForwardType
]]

$if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]]

$for UNBOUND_ARG , [[
typename CallbackParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)
]]
)>
               ::MakeItSo(storage->runnable_
$if ARITY > 0[[, ]] $for ARG , [[CallbackForward(x$(ARG))]]);
  }
};

]] $$ for BOUND
]] $$ for ARITY


// BindState<>
//
// This stores all the state passed into Bind() and is also where most
// of the template resolution magic occurs.
//
// Runnable is the functor we are binding arguments to.
// RunType is type of the Run() function that the Invoker<> should use.
// Normally, this is the same as the RunType of the Runnable, but it can
// be different if an adapter like IgnoreResult() has been used.
//
// BoundArgsType contains the storage type for all the bound arguments by
// (ab)using a function type.
template <typename Runnable, typename RunType, typename BoundArgsType>
struct BindState;

$for ARITY [[
$range ARG 1..ARITY

template <typename Runnable, typename RunType[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename P$(ARG)]]>
struct BindState<Runnable, RunType, void($for ARG , [[P$(ARG)]])> : public BindStateBase {
  typedef Runnable RunnableType;

$if ARITY > 0 [[
  typedef IsWeakMethod<HasIsMethodTag<Runnable>::value, P1> IsWeakCall;
]] $else [[
  typedef false_type IsWeakCall;
]]

  typedef Invoker<$(ARITY), BindState, RunType> InvokerType;
  typedef typename InvokerType::UnboundRunType UnboundRunType;

$if ARITY > 0 [[

  // Convenience typedefs for bound argument types.

$for ARG [[
  typedef UnwrapTraits<P$(ARG)> Bound$(ARG)UnwrapTraits;

]]  $$ for ARG


]]  $$ if ARITY > 0

$$ The extra [[ ]] is needed to massage spacing. Silly pump.py.
[[  ]]$if ARITY == 0 [[explicit ]]BindState(const Runnable& runnable
$if ARITY > 0 [[, ]] $for ARG , [[const P$(ARG)& p$(ARG)]])
      : runnable_(runnable)[[]]
$if ARITY == 0 [[
 {

]] $else [[
, $for ARG , [[

        p$(ARG)_(p$(ARG))
]] {
    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::AddRef(p1_);

]]
  }

  virtual ~BindState() {
$if ARITY > 0 [[
    MaybeRefcount<HasIsMethodTag<Runnable>::value, P1>::Release(p1_);
]]
  }

  RunnableType runnable_;

$for ARG [[
  P$(ARG) p$(ARG)_;

]]
};

]] $$ for ARITY

}  // namespace internal
}  // namespace base

#endif  // BASE_BIND_INTERNAL_H_
