$$ 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 gutil/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 GUTIL_BIND_INTERNAL_H_
#define GUTIL_BIND_INTERNAL_H_

#include "gutil/bind_helpers.h"
#include "gutil/callback_internal.h"
#include "gutil/raw_scoped_refptr_mismatch_checker.h"
#include "gutil/template_util.h"

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

// During Chromium import, WeakPtr-related code was removed.

namespace kudu {
namespace internal {

// See gutil/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 base::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 base::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))]]);
  }
};

]] $$ for ARITY

// 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;

  typedef base::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 kudu

#endif  // GUTIL_BIND_INTERNAL_H_
