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

$var MAX_ARITY = 6

// 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_
#pragma once

#include "base/bind_helpers.h"
#include "base/callback_internal.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 {

// The method by which a function is invoked is determined by 3 different
// dimensions:
//
//   1) The type of function (normal or method).
//   2) The arity of the function.
//   3) The number of bound parameters.
//
// The templates below handle the determination of each of these dimensions.
// In brief:
//
//   FunctionTraits<> -- Provides a normalied signature, and other traits.
//   InvokerN<> -- Provides a DoInvoke() function that actually executes
//                 a calback.
//   InvokerStorageN<> -- Provides storage for the bound parameters, and
//                        typedefs to the above.
//   IsWeakMethod<> -- Determines if we are binding a method to a WeakPtr<>.
//
// More details about the design of each class is included in a comment closer
// to their defition.


// IsWeakMethod determines if we are binding a method to a WeakPtr<> for an
// object.  It is used to select an InvokerN that will no-op itself in the
// event the WeakPtr<> for the target object is invalidated.
template <bool IsMethod, typename T>
struct IsWeakMethod : public false_type {};

template <typename T>
struct IsWeakMethod<true, WeakPtr<T> > : public true_type {};

// FunctionTraits<>
//
// The FunctionTraits<> template determines the type of function, and also
// creates a NormalizedType used to select the InvokerN classes.  It turns out
// that syntactically, you only really have 2 variations when invoking a
// funciton pointer: normal, and method.  One is invoked func_ptr(arg1). The
// other is invoked (*obj_->method_ptr(arg1)).
//
// However, in the type system, there are many more distinctions. In standard
// C++, there's all variations of const, and volatile on the function pointer.
// In Windows, there are additional calling conventions (eg., __stdcall,
// __fastcall, etc.). FunctionTraits<> handles categorizing each of these into
// a normalized signature.
//
// Having a NormalizedSignature signature, reduces the combinatoric
// complexity of defintions for the InvokerN<> later.  Even though there are
// only 2 syntactic variations on invoking a function, without normalizing the
// signature, there would need to be one specialization of InvokerN for each
// unique (function_type, bound_arg, unbound_args) tuple in order to match all
// function signatures.
//
// By normalizing the function signature, we reduce function_type to exactly 2.

template <typename Sig>
struct FunctionTraits;

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

// Function: Arity $(ARITY).
template <typename R[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(*)($for ARG , [[X$(ARG)]])> {
  typedef R (*NormalizedSig)($for ARG , [[X$(ARG)]]);
  typedef false_type IsMethod;

  typedef R Return;

$if ARITY > 0 [[

  // Target type for each bound parameter.

$for ARG [[
  typedef X$(ARG) B$(ARG);

]]  $$ for ARG
]]  $$ if ARITY > 0

};

// Method: Arity $(ARITY).
template <typename R, typename T[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]])> {
  typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
  typedef true_type IsMethod;

  typedef R Return;

  // Target type for each bound parameter.
  typedef T B1;

$for ARG [[
  typedef X$(ARG) B$(ARG + 1);

]]  $$ for ARG

};

// Const Method: Arity $(ARITY).
template <typename R, typename T[[]]
$if ARITY > 0[[, ]] $for ARG , [[typename X$(ARG)]]>
struct FunctionTraits<R(T::*)($for ARG , [[X$(ARG)]]) const> {
  typedef R (T::*NormalizedSig)($for ARG , [[X$(ARG)]]);
  typedef true_type IsMethod;

  typedef R Return;

  // Target type for each bound parameter.
  typedef T B1;

$for ARG [[
  typedef X$(ARG) B$(ARG + 1);

]]  $$ for ARG

};

]]  $$for ARITY

// InvokerN<>
//
// The InvokerN templates contain a static DoInvoke() function that is the key
// to implementing type erasure in the Callback() classes.
//
// DoInvoke() is a static function with a fixed signature that is independent
// of StorageType; its first argument is a pointer to the non-templated common
// baseclass of StorageType. This lets us store pointer to DoInvoke() in a
// function pointer that has knowledge of the specific StorageType, and thus
// no knowledge of the bound function and bound parameter types.
//
// As long as we ensure that DoInvoke() is only used with pointers there were
// upcasted from the correct StorageType, we can be sure that execution is
// safe.
//
// The InvokerN templates are the only point that knows the number of bound
// and unbound arguments.  This is intentional because it allows the other
// templates classes in the system to only have as many specializations as
// the max arity of function we wish to support.

$range BOUND 0..MAX_ARITY
$for BOUND [[

template <bool IsWeak, typename StorageType, typename NormalizedSig>
struct Invoker$(BOUND);

$range ARITY 0..MAX_ARITY
$for ARITY [[

$var UNBOUND = ARITY - BOUND
$if UNBOUND >= 0 [[

$$ Variables for function traits generation.
$range ARG 1..ARITY
$range BOUND_ARG 1..BOUND
$range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY

$$ Variables for method traits generation. We are always short one arity since
$$ the first bound parameter is the object.
$var M_ARITY = ARITY - 1
$range M_ARG 1..M_ARITY
$range M_BOUND_ARG 2..BOUND
$range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY

// Function: Arity $(ARITY) -> $(UNBOUND).
template <typename StorageType, typename R[[]]
$if ARITY > 0 [[,]][[]]
$for ARG , [[typename X$(ARG)]]>
struct Invoker$(BOUND)<false, StorageType, R(*)($for ARG , [[X$(ARG)]])> {
  typedef R(*DoInvokeType)(
      internal::InvokerStorageBase*[[]]
$if UNBOUND != 0 [[, ]]
$for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardType]]);

  static R DoInvoke(InvokerStorageBase* base[[]]
$if UNBOUND != 0 [[, ]][[]]
$for UNBOUND_ARG , [[typename internal::ParamTraits<X$(UNBOUND_ARG)>::ForwardType x$(UNBOUND_ARG)]]) {
    StorageType* invoker = static_cast<StorageType*>(base);
    return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]]
$$ Add comma if there are both boudn and unbound args.
$if UNBOUND > 0 [[$if BOUND > 0 [[, ]]]][[]]
$for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]);
  }
};

$if BOUND > 0 [[

// Method: Arity $(M_ARITY) -> $(UNBOUND).
template <typename StorageType, typename R, typename T[[]]
$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
struct Invoker$(BOUND)<false, StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]])> {
  typedef R(*DoInvokeType)(
      internal::InvokerStorageBase*[[]]
$if UNBOUND != 0 [[, ]]
$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType]]);

  static R DoInvoke(InvokerStorageBase* base[[]]
$if UNBOUND > 0 [[, ]][[]]
$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType x$(M_UNBOUND_ARG)]]) {
    StorageType* invoker = static_cast<StorageType*>(base);
    return (Unwrap(invoker->p1_)->*invoker->f_)([[]]
$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
$if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
$for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
  }
};

// WeakPtr Method: Arity $(M_ARITY) -> $(UNBOUND).
template <typename StorageType, typename T[[]]
$if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]>
struct Invoker$(BOUND)<true, StorageType, void(T::*)($for M_ARG , [[X$(M_ARG)]])> {
  typedef void(*DoInvokeType)(
      internal::InvokerStorageBase*[[]]
$if UNBOUND != 0 [[, ]]
$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType]]);

  static void DoInvoke(InvokerStorageBase* base[[]]
$if UNBOUND > 0 [[, ]][[]]
$for M_UNBOUND_ARG , [[typename internal::ParamTraits<X$(M_UNBOUND_ARG)>::ForwardType x$(M_UNBOUND_ARG)]]) {
    StorageType* invoker = static_cast<StorageType*>(base);
    typename StorageType::P1Traits::StorageType& weak_ptr = invoker->p1_;
    if (!weak_ptr.get()) {
      return;
    }
    (weak_ptr->*invoker->f_)([[]]
$for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]]
$if UNBOUND > 0 [[$if BOUND > 1 [[, ]]]][[]]
$for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]);
  }
};

]]  $$ if BOUND

]]  $$ if UNBOUND
]]  $$ for ARITY
]]  $$ for BOUND

// InvokerStorageN<>
//
// These are the actual storage classes for the Invokers.
//
// Though these types are "classes", they are being used as structs with
// all member variable public.  We cannot make it a struct because it inherits
// from a class which causes a compiler warning.  We cannot add a "Run()" method
// that forwards the unbound arguments because that would require we unwrap the
// Sig type like in InvokerN above to know the return type, and the arity
// of Run().
//
// An alternate solution would be to merge InvokerN and InvokerStorageN,
// but the generated code seemed harder to read.

$for BOUND [[
$range BOUND_ARG 1..BOUND

template <typename Sig[[]]
$if BOUND > 0 [[, ]]
$for BOUND_ARG , [[typename P$(BOUND_ARG)]]>
class InvokerStorage$(BOUND) : public InvokerStorageBase {
 public:
  typedef InvokerStorage$(BOUND) StorageType;
  typedef FunctionTraits<Sig> TargetTraits;
  typedef typename TargetTraits::IsMethod IsMethod;
  typedef Sig Signature;

$for BOUND_ARG [[
  typedef ParamTraits<P$(BOUND_ARG)> P$(BOUND_ARG)Traits;

]]

$if BOUND == 0 [[
  typedef Invoker$(BOUND)<false, StorageType,
                   typename TargetTraits::NormalizedSig> Invoker;
]] $else [[
  typedef Invoker$(BOUND)<IsWeakMethod<IsMethod::value, P1>::value, StorageType,
                   typename TargetTraits::NormalizedSig> Invoker;
  COMPILE_ASSERT(!(IsWeakMethod<IsMethod::value, P1>::value) ||
                 is_void<typename TargetTraits::Return>::value,
                 weak_ptrs_can_only_bind_to_methods_without_return_values);
]]


$for BOUND_ARG [[
$if BOUND_ARG == 1 [[

  // For methods, we need to be careful for parameter 1.  We skip the
  // scoped_refptr check because the binder itself takes care of this. We also
  // disallow binding of an array as the method's target object.
  COMPILE_ASSERT(IsMethod::value ||
                 !internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value,
                 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr);
  COMPILE_ASSERT(!IsMethod::value || !is_array<P$(BOUND_ARG)>::value,
                 first_bound_argument_to_method_cannot_be_array);
]] $else [[

  COMPILE_ASSERT(!internal::UnsafeBindtoRefCountedArg<P$(BOUND_ARG)>::value,
                 p$(BOUND_ARG)_is_refcounted_type_and_needs_scoped_refptr);
]]  $$ $if BOUND_ARG
]]  $$ $for BOUND_ARG


$if BOUND > 0 [[

  // 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 BOUND_ARG || [[ is_non_const_reference<typename TargetTraits::B$(BOUND_ARG)>::value ]]),
      do_not_bind_functions_with_nonconst_ref);

]]


  InvokerStorage$(BOUND)(Sig f
$if BOUND > 0 [[, ]]
$for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]])
      : f_(f)[[]]
$if BOUND == 0 [[
 {

]] $else [[
, $for BOUND_ARG , [[p$(BOUND_ARG)_(static_cast<typename ParamTraits<P$(BOUND_ARG)>::StorageType>(p$(BOUND_ARG)))]] {
    MaybeRefcount<IsMethod, P1>::AddRef(p1_);

]]
  }

  virtual ~InvokerStorage$(BOUND)() {
$if BOUND > 0 [[

    MaybeRefcount<IsMethod, P1>::Release(p1_);

]]
  }

  Sig f_;

$for BOUND_ARG [[
  typename ParamTraits<P$(BOUND_ARG)>::StorageType p$(BOUND_ARG)_;

]]
};

]]  $$ for BOUND

}  // namespace internal
}  // namespace base

#endif  // BASE_BIND_INTERNAL_H_
