// This file was GENERATED by command:
//     pump.py callback.h.pump
// DO NOT EDIT BY HAND!!!


// Copyright (c) 2012 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_CALLBACK_H_
#define BASE_CALLBACK_H_

#include "base/callback_forward.h"
#include "base/callback_internal.h"
#include "base/template_util.h"

// NOTE: Header files that do not require the full definition of Callback or
// Closure should #include "base/callback_forward.h" instead of this file.

// -----------------------------------------------------------------------------
// Introduction
// -----------------------------------------------------------------------------
//
// The templated Callback class is a generalized function object. Together
// with the Bind() function in bind.h, they provide a type-safe method for
// performing partial application of functions.
//
// Partial application (or "currying") is the process of binding a subset of
// a function's arguments to produce another function that takes fewer
// arguments. This can be used to pass around a unit of delayed execution,
// much like lexical closures are used in other languages. For example, it
// is used in Chromium code to schedule tasks on different MessageLoops.
//
// A callback with no unbound input parameters (base::Callback<void(void)>)
// is called a base::Closure. Note that this is NOT the same as what other
// languages refer to as a closure -- it does not retain a reference to its
// enclosing environment.
//
// MEMORY MANAGEMENT AND PASSING
//
// The Callback objects themselves should be passed by const-reference, and
// stored by copy. They internally store their state via a refcounted class
// and thus do not need to be deleted.
//
// The reason to pass via a const-reference is to avoid unnecessary
// AddRef/Release pairs to the internal state.
//
//
// -----------------------------------------------------------------------------
// Quick reference for basic stuff
// -----------------------------------------------------------------------------
//
// BINDING A BARE FUNCTION
//
//   int Return5() { return 5; }
//   base::Callback<int(void)> func_cb = base::Bind(&Return5);
//   LOG(INFO) << func_cb.Run();  // Prints 5.
//
// BINDING A CLASS METHOD
//
//   The first argument to bind is the member function to call, the second is
//   the object on which to call it.
//
//   class Ref : public base::RefCountedThreadSafe<Ref> {
//    public:
//     int Foo() { return 3; }
//     void PrintBye() { LOG(INFO) << "bye."; }
//   };
//   scoped_refptr<Ref> ref = new Ref();
//   base::Callback<void(void)> ref_cb = base::Bind(&Ref::Foo, ref);
//   LOG(INFO) << ref_cb.Run();  // Prints out 3.
//
//   By default the object must support RefCounted or you will get a compiler
//   error. If you're passing between threads, be sure it's
//   RefCountedThreadSafe! See "Advanced binding of member functions" below if
//   you don't want to use reference counting.
//
// RUNNING A CALLBACK
//
//   Callbacks can be run with their "Run" method, which has the same
//   signature as the template argument to the callback.
//
//   void DoSomething(const base::Callback<void(int, std::string)>& callback) {
//     callback.Run(5, "hello");
//   }
//
//   Callbacks can be run more than once (they don't get deleted or marked when
//   run). However, this precludes using base::Passed (see below).
//
//   void DoSomething(const base::Callback<double(double)>& callback) {
//     double myresult = callback.Run(3.14159);
//     myresult += callback.Run(2.71828);
//   }
//
// PASSING UNBOUND INPUT PARAMETERS
//
//   Unbound parameters are specified at the time a callback is Run(). They are
//   specified in the Callback template type:
//
//   void MyFunc(int i, const std::string& str) {}
//   base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);
//   cb.Run(23, "hello, world");
//
// PASSING BOUND INPUT PARAMETERS
//
//   Bound parameters are specified when you create thee callback as arguments
//   to Bind(). They will be passed to the function and the Run()ner of the
//   callback doesn't see those values or even know that the function it's
//   calling.
//
//   void MyFunc(int i, const std::string& str) {}
//   base::Callback<void(void)> cb = base::Bind(&MyFunc, 23, "hello world");
//   cb.Run();
//
//   A callback with no unbound input parameters (base::Callback<void(void)>)
//   is called a base::Closure. So we could have also written:
//
//   base::Closure cb = base::Bind(&MyFunc, 23, "hello world");
//
//   When calling member functions, bound parameters just go after the object
//   pointer.
//
//   base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");
//
// PARTIAL BINDING OF PARAMETERS
//
//   You can specify some parameters when you create the callback, and specify
//   the rest when you execute the callback.
//
//   void MyFunc(int i, const std::string& str) {}
//   base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23);
//   cb.Run("hello world");
//
//   When calling a function bound parameters are first, followed by unbound
//   parameters.
//
//
// -----------------------------------------------------------------------------
// Quick reference for advanced binding
// -----------------------------------------------------------------------------
//
// BINDING A CLASS METHOD WITH WEAK POINTERS
//
//   base::Bind(&MyClass::Foo, GetWeakPtr());
//
//   The callback will not be run if the object has already been destroyed.
//   DANGER: weak pointers are not threadsafe, so don't use this
//   when passing between threads!
//
// BINDING A CLASS METHOD WITH MANUAL LIFETIME MANAGEMENT
//
//   base::Bind(&MyClass::Foo, base::Unretained(this));
//
//   This disables all lifetime management on the object. You're responsible
//   for making sure the object is alive at the time of the call. You break it,
//   you own it!
//
// BINDING A CLASS METHOD AND HAVING THE CALLBACK OWN THE CLASS
//
//   MyClass* myclass = new MyClass;
//   base::Bind(&MyClass::Foo, base::Owned(myclass));
//
//   The object will be deleted when the callback is destroyed, even if it's
//   not run (like if you post a task during shutdown). Potentially useful for
//   "fire and forget" cases.
//
// IGNORING RETURN VALUES
//
//   Sometimes you want to call a function that returns a value in a callback
//   that doesn't expect a return value.
//
//   int DoSomething(int arg) { cout << arg << endl; }
//   base::Callback<void<int>) cb =
//       base::Bind(base::IgnoreResult(&DoSomething));
//
//
// -----------------------------------------------------------------------------
// Quick reference for binding parameters to Bind()
// -----------------------------------------------------------------------------
//
// Bound parameters are specified as arguments to Bind() and are passed to the
// function. A callback with no parameters or no unbound parameters is called a
// Closure (base::Callback<void(void)> and base::Closure are the same thing).
//
// PASSING PARAMETERS OWNED BY THE CALLBACK
//
//   void Foo(int* arg) { cout << *arg << endl; }
//   int* pn = new int(1);
//   base::Closure foo_callback = base::Bind(&foo, base::Owned(pn));
//
//   The parameter will be deleted when the callback is destroyed, even if it's
//   not run (like if you post a task during shutdown).
//
// PASSING PARAMETERS AS A scoped_ptr
//
//   void TakesOwnership(scoped_ptr<Foo> arg) {}
//   scoped_ptr<Foo> f(new Foo);
//   // f becomes null during the following call.
//   base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f));
//
//   Ownership of the parameter will be with the callback until the it is run,
//   when ownership is passed to the callback function. This means the callback
//   can only be run once. If the callback is never run, it will delete the
//   object when it's destroyed.
//
// PASSING PARAMETERS AS A scoped_refptr
//
//   void TakesOneRef(scoped_refptr<Foo> arg) {}
//   scoped_refptr<Foo> f(new Foo)
//   base::Closure cb = base::Bind(&TakesOneRef, f);
//
//   This should "just work." The closure will take a reference as long as it
//   is alive, and another reference will be taken for the called function.
//
// PASSING PARAMETERS BY REFERENCE
//
//   Const references are *copied* unless ConstRef is used. Example:
//
//   void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
//   int n = 1;
//   base::Closure has_copy = base::Bind(&foo, n);
//   base::Closure has_ref = base::Bind(&foo, base::ConstRef(n));
//   n = 2;
//   foo(n);                        // Prints "2 0xaaaaaaaaaaaa"
//   has_copy.Run();                // Prints "1 0xbbbbbbbbbbbb"
//   has_ref.Run();                 // Prints "2 0xaaaaaaaaaaaa"
//
//   Normally parameters are copied in the closure. DANGER: ConstRef stores a
//   const reference instead, referencing the original parameter. This means
//   that you must ensure the object outlives the callback!
//
//
// -----------------------------------------------------------------------------
// Implementation notes
// -----------------------------------------------------------------------------
//
// WHERE IS THIS DESIGN FROM:
//
// The design Callback and Bind is heavily influenced by C++'s
// tr1::function/tr1::bind, and by the "Google Callback" system used inside
// Google.
//
//
// HOW THE IMPLEMENTATION WORKS:
//
// There are three main components to the system:
//   1) The Callback classes.
//   2) The Bind() functions.
//   3) The arguments wrappers (e.g., Unretained() and ConstRef()).
//
// The Callback classes represent a generic function pointer. Internally,
// it stores a refcounted piece of state that represents the target function
// and all its bound parameters.  Each Callback specialization has a templated
// constructor that takes an BindState<>*.  In the context of the constructor,
// the static type of this BindState<> pointer uniquely identifies the
// function it is representing, all its bound parameters, and a Run() method
// that is capable of invoking the target.
//
// Callback's constructor takes the BindState<>* that has the full static type
// and erases the target function type as well as the types of the bound
// parameters.  It does this by storing a pointer to the specific Run()
// function, and upcasting the state of BindState<>* to a
// BindStateBase*. This is safe as long as this BindStateBase pointer
// is only used with the stored Run() pointer.
//
// To BindState<> objects are created inside the Bind() functions.
// These functions, along with a set of internal templates, are responsible for
//
//  - Unwrapping the function signature into return type, and parameters
//  - Determining the number of parameters that are bound
//  - Creating the BindState storing the bound parameters
//  - Performing compile-time asserts to avoid error-prone behavior
//  - Returning an Callback<> with an arity matching the number of unbound
//    parameters and that knows the correct refcounting semantics for the
//    target object if we are binding a method.
//
// The Bind functions do the above using type-inference, and template
// specializations.
//
// By default Bind() will store copies of all bound parameters, and attempt
// to refcount a target object if the function being bound is a class method.
// These copies are created even if the function takes parameters as const
// references. (Binding to non-const references is forbidden, see bind.h.)
//
// To change this behavior, we introduce a set of argument wrappers
// (e.g., Unretained(), and ConstRef()).  These are simple container templates
// that are passed by value, and wrap a pointer to argument.  See the
// file-level comment in base/bind_helpers.h for more info.
//
// These types are passed to the Unwrap() functions, and the MaybeRefcount()
// functions respectively to modify the behavior of Bind().  The Unwrap()
// and MaybeRefcount() functions change behavior by doing partial
// specialization based on whether or not a parameter is a wrapper type.
//
// ConstRef() is similar to tr1::cref.  Unretained() is specific to Chromium.
//
//
// WHY NOT TR1 FUNCTION/BIND?
//
// Direct use of tr1::function and tr1::bind was considered, but ultimately
// rejected because of the number of copy constructors invocations involved
// in the binding of arguments during construction, and the forwarding of
// arguments during invocation.  These copies will no longer be an issue in
// C++0x because C++0x will support rvalue reference allowing for the compiler
// to avoid these copies.  However, waiting for C++0x is not an option.
//
// Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
// tr1::bind call itself will invoke a non-trivial copy constructor three times
// for each bound parameter.  Also, each when passing a tr1::function, each
// bound argument will be copied again.
//
// In addition to the copies taken at binding and invocation, copying a
// tr1::function causes a copy to be made of all the bound parameters and
// state.
//
// Furthermore, in Chromium, it is desirable for the Callback to take a
// reference on a target object when representing a class method call.  This
// is not supported by tr1.
//
// Lastly, tr1::function and tr1::bind has a more general and flexible API.
// This includes things like argument reordering by use of
// tr1::bind::placeholder, support for non-const reference parameters, and some
// limited amount of subtyping of the tr1::function object (e.g.,
// tr1::function<int(int)> is convertible to tr1::function<void(int)>).
//
// These are not features that are required in Chromium. Some of them, such as
// allowing for reference parameters, and subtyping of functions, may actually
// become a source of errors. Removing support for these features actually
// allows for a simpler implementation, and a terser Currying API.
//
//
// WHY NOT GOOGLE CALLBACKS?
//
// The Google callback system also does not support refcounting.  Furthermore,
// its implementation has a number of strange edge cases with respect to type
// conversion of its arguments.  In particular, the argument's constness must
// at times match exactly the function signature, or the type-inference might
// break.  Given the above, writing a custom solution was easier.
//
//
// MISSING FUNCTIONALITY
//  - Invoking the return of Bind.  Bind(&foo).Run() does not work;
//  - Binding arrays to functions that take a non-const pointer.
//    Example:
//      void Foo(const char* ptr);
//      void Bar(char* ptr);
//      Bind(&Foo, "test");
//      Bind(&Bar, "test");  // This fails because ptr is not const.

namespace base {

// First, we forward declare the Callback class template. This informs the
// compiler that the template only has 1 type parameter which is the function
// signature that the Callback is representing.
//
// After this, create template specializations for 0-7 parameters. Note that
// even though the template typelist grows, the specialization still
// only has one type: the function signature.
//
// If you are thinking of forward declaring Callback in your own header file,
// please include "base/callback_forward.h" instead.
template <typename Sig>
class Callback;

namespace internal {
template <typename Runnable, typename RunType, typename BoundArgsType>
struct BindState;
}  // namespace internal

template <typename R>
class Callback<R(void)> : public internal::CallbackBase {
 public:
  typedef R(RunType)();

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run() const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get());
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*);

};

template <typename R, typename A1>
class Callback<R(A1)> : public internal::CallbackBase {
 public:
  typedef R(RunType)(A1);

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1) const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get(), internal::CallbackForward(a1));
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*,
          typename internal::CallbackParamTraits<A1>::ForwardType);

};

template <typename R, typename A1, typename A2>
class Callback<R(A1, A2)> : public internal::CallbackBase {
 public:
  typedef R(RunType)(A1, A2);

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
        typename internal::CallbackParamTraits<A2>::ForwardType a2) const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get(), internal::CallbackForward(a1),
             internal::CallbackForward(a2));
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*,
          typename internal::CallbackParamTraits<A1>::ForwardType,
          typename internal::CallbackParamTraits<A2>::ForwardType);

};

template <typename R, typename A1, typename A2, typename A3>
class Callback<R(A1, A2, A3)> : public internal::CallbackBase {
 public:
  typedef R(RunType)(A1, A2, A3);

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
        typename internal::CallbackParamTraits<A2>::ForwardType a2,
        typename internal::CallbackParamTraits<A3>::ForwardType a3) const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get(), internal::CallbackForward(a1),
             internal::CallbackForward(a2),
             internal::CallbackForward(a3));
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*,
          typename internal::CallbackParamTraits<A1>::ForwardType,
          typename internal::CallbackParamTraits<A2>::ForwardType,
          typename internal::CallbackParamTraits<A3>::ForwardType);

};

template <typename R, typename A1, typename A2, typename A3, typename A4>
class Callback<R(A1, A2, A3, A4)> : public internal::CallbackBase {
 public:
  typedef R(RunType)(A1, A2, A3, A4);

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
        typename internal::CallbackParamTraits<A2>::ForwardType a2,
        typename internal::CallbackParamTraits<A3>::ForwardType a3,
        typename internal::CallbackParamTraits<A4>::ForwardType a4) const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get(), internal::CallbackForward(a1),
             internal::CallbackForward(a2),
             internal::CallbackForward(a3),
             internal::CallbackForward(a4));
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*,
          typename internal::CallbackParamTraits<A1>::ForwardType,
          typename internal::CallbackParamTraits<A2>::ForwardType,
          typename internal::CallbackParamTraits<A3>::ForwardType,
          typename internal::CallbackParamTraits<A4>::ForwardType);

};

template <typename R, typename A1, typename A2, typename A3, typename A4,
    typename A5>
class Callback<R(A1, A2, A3, A4, A5)> : public internal::CallbackBase {
 public:
  typedef R(RunType)(A1, A2, A3, A4, A5);

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
        typename internal::CallbackParamTraits<A2>::ForwardType a2,
        typename internal::CallbackParamTraits<A3>::ForwardType a3,
        typename internal::CallbackParamTraits<A4>::ForwardType a4,
        typename internal::CallbackParamTraits<A5>::ForwardType a5) const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get(), internal::CallbackForward(a1),
             internal::CallbackForward(a2),
             internal::CallbackForward(a3),
             internal::CallbackForward(a4),
             internal::CallbackForward(a5));
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*,
          typename internal::CallbackParamTraits<A1>::ForwardType,
          typename internal::CallbackParamTraits<A2>::ForwardType,
          typename internal::CallbackParamTraits<A3>::ForwardType,
          typename internal::CallbackParamTraits<A4>::ForwardType,
          typename internal::CallbackParamTraits<A5>::ForwardType);

};

template <typename R, typename A1, typename A2, typename A3, typename A4,
    typename A5, typename A6>
class Callback<R(A1, A2, A3, A4, A5, A6)> : public internal::CallbackBase {
 public:
  typedef R(RunType)(A1, A2, A3, A4, A5, A6);

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
        typename internal::CallbackParamTraits<A2>::ForwardType a2,
        typename internal::CallbackParamTraits<A3>::ForwardType a3,
        typename internal::CallbackParamTraits<A4>::ForwardType a4,
        typename internal::CallbackParamTraits<A5>::ForwardType a5,
        typename internal::CallbackParamTraits<A6>::ForwardType a6) const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get(), internal::CallbackForward(a1),
             internal::CallbackForward(a2),
             internal::CallbackForward(a3),
             internal::CallbackForward(a4),
             internal::CallbackForward(a5),
             internal::CallbackForward(a6));
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*,
          typename internal::CallbackParamTraits<A1>::ForwardType,
          typename internal::CallbackParamTraits<A2>::ForwardType,
          typename internal::CallbackParamTraits<A3>::ForwardType,
          typename internal::CallbackParamTraits<A4>::ForwardType,
          typename internal::CallbackParamTraits<A5>::ForwardType,
          typename internal::CallbackParamTraits<A6>::ForwardType);

};

template <typename R, typename A1, typename A2, typename A3, typename A4,
    typename A5, typename A6, typename A7>
class Callback<R(A1, A2, A3, A4, A5, A6, A7)> : public internal::CallbackBase {
 public:
  typedef R(RunType)(A1, A2, A3, A4, A5, A6, A7);

  Callback() : CallbackBase(NULL) { }

  // Note that this constructor CANNOT be explicit, and that Bind() CANNOT
  // return the exact Callback<> type.  See base/bind.h for details.
  template <typename Runnable, typename BindRunType, typename BoundArgsType>
  Callback(internal::BindState<Runnable, BindRunType,
           BoundArgsType>* bind_state)
      : CallbackBase(bind_state) {

    // Force the assignment to a local variable of PolymorphicInvoke
    // so the compiler will typecheck that the passed in Run() method has
    // the correct type.
    PolymorphicInvoke invoke_func =
        &internal::BindState<Runnable, BindRunType, BoundArgsType>
            ::InvokerType::Run;
    polymorphic_invoke_ = reinterpret_cast<InvokeFuncStorage>(invoke_func);
  }

  bool Equals(const Callback& other) const {
    return CallbackBase::Equals(other);
  }

  R Run(typename internal::CallbackParamTraits<A1>::ForwardType a1,
        typename internal::CallbackParamTraits<A2>::ForwardType a2,
        typename internal::CallbackParamTraits<A3>::ForwardType a3,
        typename internal::CallbackParamTraits<A4>::ForwardType a4,
        typename internal::CallbackParamTraits<A5>::ForwardType a5,
        typename internal::CallbackParamTraits<A6>::ForwardType a6,
        typename internal::CallbackParamTraits<A7>::ForwardType a7) const {
    PolymorphicInvoke f =
        reinterpret_cast<PolymorphicInvoke>(polymorphic_invoke_);

    return f(bind_state_.get(), internal::CallbackForward(a1),
             internal::CallbackForward(a2),
             internal::CallbackForward(a3),
             internal::CallbackForward(a4),
             internal::CallbackForward(a5),
             internal::CallbackForward(a6),
             internal::CallbackForward(a7));
  }

 private:
  typedef R(*PolymorphicInvoke)(
      internal::BindStateBase*,
          typename internal::CallbackParamTraits<A1>::ForwardType,
          typename internal::CallbackParamTraits<A2>::ForwardType,
          typename internal::CallbackParamTraits<A3>::ForwardType,
          typename internal::CallbackParamTraits<A4>::ForwardType,
          typename internal::CallbackParamTraits<A5>::ForwardType,
          typename internal::CallbackParamTraits<A6>::ForwardType,
          typename internal::CallbackParamTraits<A7>::ForwardType);

};


// Syntactic sugar to make Callback<void(void)> easier to declare since it
// will be used in a lot of APIs with delayed execution.
typedef Callback<void(void)> Closure;

}  // namespace base

#endif  // BASE_CALLBACK_H
