$$ 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(__LB_SHELL__) || defined(OS_STARBOARD)
// Check for C++11 support
#if (_MSC_VER >=  1700) || (__cplusplus > 199711L)
#include "base/bind_internal_functor.h"
#endif
#endif

#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

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[[]], $for ARG , [[typename A$(ARG)]]>
struct InvokeHelper<true, void, Runnable,
    void($for ARG , [[A$(ARG)]])>  {
  static void MakeItSo(Runnable runnable[[]]
$if ARITY > 0[[, ]] $for ARG , [[A$(ARG) a$(ARG)]]) {
    if (!a1.get()) {
      return;
    }

    runnable.Run($for ARG , [[CallbackForward(a$(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_
