/* Copyright 2020 Alibaba Group Holding Limited. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#ifndef GRAPHLEARN_COMMON_BASE_CLOSURE_H_
#define GRAPHLEARN_COMMON_BASE_CLOSURE_H_

#include "google/protobuf/stubs/callback.h"
#include "platform/protobuf.h"

namespace graphlearn {

class ClosureBase {
public:
  virtual ~ClosureBase() { }
  virtual bool IsAutoDelete() const = 0;
};

// This is the main Template Class. Because we want to use the same name
// "Closure" for different type combination, we need to use template
// specialization.
template<
  typename R,
  typename A1 = void,
  typename A2 = void,
  typename A3 = void,
  typename A4 = void,
  typename A5 = void,
  typename A6 = void,
  typename A7 = void,
  typename A8 = void >
class Closure : public ClosureBase {
public:
  virtual R Run(
    A1 a1,
    A2 a2,
    A3 a3,
    A4 a4,
    A5 a5,
    A6 a6,
    A7 a7,
    A8 a8
  ) = 0;  // NOLINT [whitespace/parens]
};

// The purpose of the following specialization is to be compatible with
// PB_NAMESPACE::Closure interface, the rpc stub generated by protobuf
// takes this as parameter.  The Closure template staff inherit from this
// interface, and the utilities provided as following could help to create
// Closure instances for protobuf usage.
// N.B.: DO NOT "using namespace google protobuf" in your code, otherwise
// the compiler will complain ambiguous definition error.
template<>
class Closure<void> : public ClosureBase, public ::PB_NAMESPACE::Closure {
public:
  virtual void Run() = 0;
};

template<
  typename R >
class Closure<R> : public ClosureBase {
public:
  virtual R Run() = 0;
};

template<
  typename R,
  typename A1 >
class Closure<R, A1> : public ClosureBase {
public:
  virtual R Run(A1) = 0;
};

template<
  typename R,
  typename A1,
  typename A2 >
class Closure<R, A1, A2> : public ClosureBase {
public:
  virtual R Run(A1, A2) = 0;
};

template<
  typename R,
  typename A1,
  typename A2,
  typename A3 >
class Closure<R, A1, A2, A3> : public ClosureBase {
public:
  virtual R Run(A1, A2, A3) = 0;
};

template<
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class Closure<R, A1, A2, A3, A4> : public ClosureBase {
public:
  virtual R Run(A1, A2, A3, A4) = 0;
};

template<
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class Closure<R, A1, A2, A3, A4, A5> : public ClosureBase {
public:
  virtual R Run(A1, A2, A3, A4, A5) = 0;
};

template<
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class Closure<R, A1, A2, A3, A4, A5, A6> : public ClosureBase {
public:
  virtual R Run(A1, A2, A3, A4, A5, A6) = 0;
};

template<
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class Closure<R, A1, A2, A3, A4, A5, A6, A7> : public ClosureBase {
public:
  virtual R Run(A1, A2, A3, A4, A5, A6, A7) = 0;
};

namespace closure {

template<bool del, typename T>
class SelfDeleter {
public:
  explicit SelfDeleter(T* obj)
    : obj_(obj)
  { }
  ~SelfDeleter() {
    if (del) {
      delete obj_;
    }
  }

private:
  SelfDeleter(const SelfDeleter&);
  SelfDeleter& operator=(const SelfDeleter&);

private:
  T* obj_;
};

template<
  bool del,
  typename R,
  typename T >
class MethodClosure_0_0 : public Closure<R>{
  typedef R (T::*Signature)();

public:
  MethodClosure_0_0(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)();
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1 >
class MethodClosure_0_1 : public Closure<R, A1>{
  typedef R (T::*Signature)(A1);

public:
  MethodClosure_0_1(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_1() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A1 a1) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1 >
class MethodClosure_1_0 : public Closure<R>{
  typedef R (T::*Signature)(A1);

public:
  MethodClosure_1_0(T* obj, Signature func, A1 a1) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1) {
  }
  ~MethodClosure_1_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2 >
class MethodClosure_0_2 : public Closure<R, A1, A2>{
  typedef R (T::*Signature)(A1, A2);

public:
  MethodClosure_0_2(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_2() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1, a2);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2 >
class MethodClosure_1_1 : public Closure<R, A2>{
  typedef R (T::*Signature)(A1, A2);

public:
  MethodClosure_1_1(T* obj, Signature func, A1 a1) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1) {
  }
  ~MethodClosure_1_1() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A2 a2) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2 >
class MethodClosure_2_0 : public Closure<R>{
  typedef R (T::*Signature)(A1, A2);

public:
  MethodClosure_2_0(T* obj, Signature func, A1 a1, A2 a2) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~MethodClosure_2_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3 >
class MethodClosure_0_3 : public Closure<R, A1, A2, A3>{
  typedef R (T::*Signature)(A1, A2, A3);

public:
  MethodClosure_0_3(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_3() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1, a2, a3);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3 >
class MethodClosure_1_2 : public Closure<R, A2, A3>{
  typedef R (T::*Signature)(A1, A2, A3);

public:
  MethodClosure_1_2(T* obj, Signature func, A1 a1) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1) {
  }
  ~MethodClosure_1_2() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2, a3);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3 >
class MethodClosure_2_1 : public Closure<R, A3>{
  typedef R (T::*Signature)(A1, A2, A3);

public:
  MethodClosure_2_1(T* obj, Signature func, A1 a1, A2 a2) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~MethodClosure_2_1() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A3 a3) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3 >
class MethodClosure_3_0 : public Closure<R>{
  typedef R (T::*Signature)(A1, A2, A3);

public:
  MethodClosure_3_0(T* obj, Signature func, A1 a1, A2 a2, A3 a3) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~MethodClosure_3_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class MethodClosure_0_4 : public Closure<R, A1, A2, A3, A4>{
  typedef R (T::*Signature)(A1, A2, A3, A4);

public:
  MethodClosure_0_4(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_4() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1, a2, a3, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class MethodClosure_1_3 : public Closure<R, A2, A3, A4>{
  typedef R (T::*Signature)(A1, A2, A3, A4);

public:
  MethodClosure_1_3(T* obj, Signature func, A1 a1) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1) {
  }
  ~MethodClosure_1_3() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2, a3, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class MethodClosure_2_2 : public Closure<R, A3, A4>{
  typedef R (T::*Signature)(A1, A2, A3, A4);

public:
  MethodClosure_2_2(T* obj, Signature func, A1 a1, A2 a2) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~MethodClosure_2_2() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class MethodClosure_3_1 : public Closure<R, A4>{
  typedef R (T::*Signature)(A1, A2, A3, A4);

public:
  MethodClosure_3_1(T* obj, Signature func, A1 a1, A2 a2, A3 a3) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~MethodClosure_3_1() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class MethodClosure_4_0 : public Closure<R>{
  typedef R (T::*Signature)(A1, A2, A3, A4);

public:
  MethodClosure_4_0(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~MethodClosure_4_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class MethodClosure_0_5 : public Closure<R, A1, A2, A3, A4, A5>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5);

public:
  MethodClosure_0_5(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_5() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1, a2, a3, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class MethodClosure_1_4 : public Closure<R, A2, A3, A4, A5>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5);

public:
  MethodClosure_1_4(T* obj, Signature func, A1 a1) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1) {
  }
  ~MethodClosure_1_4() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2, a3, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class MethodClosure_2_3 : public Closure<R, A3, A4, A5>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5);

public:
  MethodClosure_2_3(T* obj, Signature func, A1 a1, A2 a2) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~MethodClosure_2_3() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class MethodClosure_3_2 : public Closure<R, A4, A5>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5);

public:
  MethodClosure_3_2(T* obj, Signature func, A1 a1, A2 a2, A3 a3) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~MethodClosure_3_2() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class MethodClosure_4_1 : public Closure<R, A5>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5);

public:
  MethodClosure_4_1(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~MethodClosure_4_1() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class MethodClosure_5_0 : public Closure<R>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5);

public:
  MethodClosure_5_0(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5) {
  }
  ~MethodClosure_5_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class MethodClosure_0_6 : public Closure<R, A1, A2, A3, A4, A5, A6>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6);

public:
  MethodClosure_0_6(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_6() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1, a2, a3, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class MethodClosure_1_5 : public Closure<R, A2, A3, A4, A5, A6>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6);

public:
  MethodClosure_1_5(T* obj, Signature func, A1 a1) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1) {
  }
  ~MethodClosure_1_5() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2, a3, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class MethodClosure_2_4 : public Closure<R, A3, A4, A5, A6>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6);

public:
  MethodClosure_2_4(T* obj, Signature func, A1 a1, A2 a2) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~MethodClosure_2_4() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class MethodClosure_3_3 : public Closure<R, A4, A5, A6>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6);

public:
  MethodClosure_3_3(T* obj, Signature func, A1 a1, A2 a2, A3 a3) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~MethodClosure_3_3() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class MethodClosure_4_2 : public Closure<R, A5, A6>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6);

public:
  MethodClosure_4_2(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~MethodClosure_4_2() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class MethodClosure_5_1 : public Closure<R, A6>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6);

public:
  MethodClosure_5_1(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5) {
  }
  ~MethodClosure_5_1() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5_, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class MethodClosure_6_0 : public Closure<R>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6);

public:
  MethodClosure_6_0(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5),
      a6_(a6) {
  }
  ~MethodClosure_6_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5_, a6_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
  A6 a6_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_0_7 : public Closure<R, A1, A2, A3, A4, A5, A6, A7>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_0_7(T* obj, Signature func) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func) {
  }
  ~MethodClosure_0_7() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1, a2, a3, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_1_6 : public Closure<R, A2, A3, A4, A5, A6, A7>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_1_6(T* obj, Signature func, A1 a1) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1) {
  }
  ~MethodClosure_1_6() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2, a3, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_2_5 : public Closure<R, A3, A4, A5, A6, A7>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_2_5(T* obj, Signature func, A1 a1, A2 a2) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~MethodClosure_2_5() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_3_4 : public Closure<R, A4, A5, A6, A7>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_3_4(T* obj, Signature func, A1 a1, A2 a2, A3 a3) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~MethodClosure_3_4() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_4_3 : public Closure<R, A5, A6, A7>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_4_3(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~MethodClosure_4_3() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_5_2 : public Closure<R, A6, A7>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_5_2(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5) {
  }
  ~MethodClosure_5_2() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5_, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_6_1 : public Closure<R, A7>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_6_1(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5),
      a6_(a6) {
  }
  ~MethodClosure_6_1() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run(A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5_, a6_, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
  A6 a6_;
};

template<
  bool del,
  typename R,
  typename T,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class MethodClosure_7_0 : public Closure<R>{
  typedef R (T::*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  MethodClosure_7_0(T* obj, Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) // NOLINT [whitespace/line_length]
    : obj_(obj),
      func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5),
      a6_(a6),
      a7_(a7) {
  }
  ~MethodClosure_7_0() {
    obj_ = nullptr;
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (obj_->*func_)(a1_, a2_, a3_, a4_, a5_, a6_, a7_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  T* obj_;
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
  A6 a6_;
  A7 a7_;
};

template<
  bool del,
  typename R >
class FunctionClosure_0_0 : public Closure<R>{
  typedef R (*Signature)();

public:
  FunctionClosure_0_0(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)();
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1 >
class FunctionClosure_0_1 : public Closure<R, A1>{
  typedef R (*Signature)(A1);

public:
  FunctionClosure_0_1(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_1() {
    func_ = nullptr;
  }
  virtual R Run(A1 a1) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1 >
class FunctionClosure_1_0 : public Closure<R>{
  typedef R (*Signature)(A1);

public:
  FunctionClosure_1_0(Signature func, A1 a1)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1) {
  }
  ~FunctionClosure_1_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2 >
class FunctionClosure_0_2 : public Closure<R, A1, A2>{
  typedef R (*Signature)(A1, A2);

public:
  FunctionClosure_0_2(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_2() {
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1, a2);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2 >
class FunctionClosure_1_1 : public Closure<R, A2>{
  typedef R (*Signature)(A1, A2);

public:
  FunctionClosure_1_1(Signature func, A1 a1)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1) {
  }
  ~FunctionClosure_1_1() {
    func_ = nullptr;
  }
  virtual R Run(A2 a2) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2 >
class FunctionClosure_2_0 : public Closure<R>{
  typedef R (*Signature)(A1, A2);

public:
  FunctionClosure_2_0(Signature func, A1 a1, A2 a2)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~FunctionClosure_2_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3 >
class FunctionClosure_0_3 : public Closure<R, A1, A2, A3>{
  typedef R (*Signature)(A1, A2, A3);

public:
  FunctionClosure_0_3(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_3() {
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1, a2, a3);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3 >
class FunctionClosure_1_2 : public Closure<R, A2, A3>{
  typedef R (*Signature)(A1, A2, A3);

public:
  FunctionClosure_1_2(Signature func, A1 a1)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1) {
  }
  ~FunctionClosure_1_2() {
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2, a3);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3 >
class FunctionClosure_2_1 : public Closure<R, A3>{
  typedef R (*Signature)(A1, A2, A3);

public:
  FunctionClosure_2_1(Signature func, A1 a1, A2 a2)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~FunctionClosure_2_1() {
    func_ = nullptr;
  }
  virtual R Run(A3 a3) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3 >
class FunctionClosure_3_0 : public Closure<R>{
  typedef R (*Signature)(A1, A2, A3);

public:
  FunctionClosure_3_0(Signature func, A1 a1, A2 a2, A3 a3)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~FunctionClosure_3_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class FunctionClosure_0_4 : public Closure<R, A1, A2, A3, A4>{
  typedef R (*Signature)(A1, A2, A3, A4);

public:
  FunctionClosure_0_4(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_4() {
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1, a2, a3, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class FunctionClosure_1_3 : public Closure<R, A2, A3, A4>{
  typedef R (*Signature)(A1, A2, A3, A4);

public:
  FunctionClosure_1_3(Signature func, A1 a1)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1) {
  }
  ~FunctionClosure_1_3() {
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2, a3, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class FunctionClosure_2_2 : public Closure<R, A3, A4>{
  typedef R (*Signature)(A1, A2, A3, A4);

public:
  FunctionClosure_2_2(Signature func, A1 a1, A2 a2)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~FunctionClosure_2_2() {
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class FunctionClosure_3_1 : public Closure<R, A4>{
  typedef R (*Signature)(A1, A2, A3, A4);

public:
  FunctionClosure_3_1(Signature func, A1 a1, A2 a2, A3 a3)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~FunctionClosure_3_1() {
    func_ = nullptr;
  }
  virtual R Run(A4 a4) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4 >
class FunctionClosure_4_0 : public Closure<R>{
  typedef R (*Signature)(A1, A2, A3, A4);

public:
  FunctionClosure_4_0(Signature func, A1 a1, A2 a2, A3 a3, A4 a4)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~FunctionClosure_4_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class FunctionClosure_0_5 : public Closure<R, A1, A2, A3, A4, A5>{
  typedef R (*Signature)(A1, A2, A3, A4, A5);

public:
  FunctionClosure_0_5(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_5() {
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1, a2, a3, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class FunctionClosure_1_4 : public Closure<R, A2, A3, A4, A5>{
  typedef R (*Signature)(A1, A2, A3, A4, A5);

public:
  FunctionClosure_1_4(Signature func, A1 a1)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1) {
  }
  ~FunctionClosure_1_4() {
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2, a3, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class FunctionClosure_2_3 : public Closure<R, A3, A4, A5>{
  typedef R (*Signature)(A1, A2, A3, A4, A5);

public:
  FunctionClosure_2_3(Signature func, A1 a1, A2 a2)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~FunctionClosure_2_3() {
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class FunctionClosure_3_2 : public Closure<R, A4, A5>{
  typedef R (*Signature)(A1, A2, A3, A4, A5);

public:
  FunctionClosure_3_2(Signature func, A1 a1, A2 a2, A3 a3)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~FunctionClosure_3_2() {
    func_ = nullptr;
  }
  virtual R Run(A4 a4, A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class FunctionClosure_4_1 : public Closure<R, A5>{
  typedef R (*Signature)(A1, A2, A3, A4, A5);

public:
  FunctionClosure_4_1(Signature func, A1 a1, A2 a2, A3 a3, A4 a4)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~FunctionClosure_4_1() {
    func_ = nullptr;
  }
  virtual R Run(A5 a5) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5 >
class FunctionClosure_5_0 : public Closure<R>{
  typedef R (*Signature)(A1, A2, A3, A4, A5);

public:
  FunctionClosure_5_0(Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5) {
  }
  ~FunctionClosure_5_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class FunctionClosure_0_6 : public Closure<R, A1, A2, A3, A4, A5, A6>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6);

public:
  FunctionClosure_0_6(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_6() {
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1, a2, a3, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class FunctionClosure_1_5 : public Closure<R, A2, A3, A4, A5, A6>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6);

public:
  FunctionClosure_1_5(Signature func, A1 a1)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1) {
  }
  ~FunctionClosure_1_5() {
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2, a3, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class FunctionClosure_2_4 : public Closure<R, A3, A4, A5, A6>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6);

public:
  FunctionClosure_2_4(Signature func, A1 a1, A2 a2)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~FunctionClosure_2_4() {
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class FunctionClosure_3_3 : public Closure<R, A4, A5, A6>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6);

public:
  FunctionClosure_3_3(Signature func, A1 a1, A2 a2, A3 a3)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~FunctionClosure_3_3() {
    func_ = nullptr;
  }
  virtual R Run(A4 a4, A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class FunctionClosure_4_2 : public Closure<R, A5, A6>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6);

public:
  FunctionClosure_4_2(Signature func, A1 a1, A2 a2, A3 a3, A4 a4)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~FunctionClosure_4_2() {
    func_ = nullptr;
  }
  virtual R Run(A5 a5, A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class FunctionClosure_5_1 : public Closure<R, A6>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6);

public:
  FunctionClosure_5_1(Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5) {
  }
  ~FunctionClosure_5_1() {
    func_ = nullptr;
  }
  virtual R Run(A6 a6) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5_, a6);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6 >
class FunctionClosure_6_0 : public Closure<R>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6);

public:
  FunctionClosure_6_0(Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5),
      a6_(a6) {
  }
  ~FunctionClosure_6_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5_, a6_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
  A6 a6_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_0_7 : public Closure<R, A1, A2, A3, A4, A5, A6, A7>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_0_7(Signature func)  //NOLINT [whitespace/blank_line]
    : func_(func) {
  }
  ~FunctionClosure_0_7() {
    func_ = nullptr;
  }
  virtual R Run(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1, a2, a3, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_1_6 : public Closure<R, A2, A3, A4, A5, A6, A7>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_1_6(Signature func, A1 a1)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1) {
  }
  ~FunctionClosure_1_6() {
    func_ = nullptr;
  }
  virtual R Run(A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2, a3, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_2_5 : public Closure<R, A3, A4, A5, A6, A7>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_2_5(Signature func, A1 a1, A2 a2)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2) {
  }
  ~FunctionClosure_2_5() {
    func_ = nullptr;
  }
  virtual R Run(A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_3_4 : public Closure<R, A4, A5, A6, A7>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_3_4(Signature func, A1 a1, A2 a2, A3 a3)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3) {
  }
  ~FunctionClosure_3_4() {
    func_ = nullptr;
  }
  virtual R Run(A4 a4, A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_4_3 : public Closure<R, A5, A6, A7>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_4_3(Signature func, A1 a1, A2 a2, A3 a3, A4 a4)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4) {
  }
  ~FunctionClosure_4_3() {
    func_ = nullptr;
  }
  virtual R Run(A5 a5, A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_5_2 : public Closure<R, A6, A7>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_5_2(Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5) {
  }
  ~FunctionClosure_5_2() {
    func_ = nullptr;
  }
  virtual R Run(A6 a6, A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5_, a6, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_6_1 : public Closure<R, A7>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_6_1(Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5),
      a6_(a6) {
  }
  ~FunctionClosure_6_1() {
    func_ = nullptr;
  }
  virtual R Run(A7 a7) {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5_, a6_, a7);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
  A6 a6_;
};

template<
  bool del,
  typename R,
  typename A1,
  typename A2,
  typename A3,
  typename A4,
  typename A5,
  typename A6,
  typename A7 >
class FunctionClosure_7_0 : public Closure<R>{
  typedef R (*Signature)(A1, A2, A3, A4, A5, A6, A7);

public:
  FunctionClosure_7_0(Signature func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)  //NOLINT [whitespace/blank_line]
    : func_(func),
      a1_(a1),
      a2_(a2),
      a3_(a3),
      a4_(a4),
      a5_(a5),
      a6_(a6),
      a7_(a7) {
  }
  ~FunctionClosure_7_0() {
    func_ = nullptr;
  }
  virtual R Run() {
    SelfDeleter<del, ClosureBase> deleter(this);
    return (func_)(a1_, a2_, a3_, a4_, a5_, a6_, a7_);
  }
  virtual bool IsAutoDelete() const {
    return del;
  }

private:
  Signature func_;
  A1 a1_;
  A2 a2_;
  A3 a3_;
  A4 a4_;
  A5 a5_;
  A6 a6_;
  A7 a7_;
};

}  // namespace closure

template<typename R, typename T>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)()) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_0<true, R, T>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1>  // NOLINT [whitespace/line_length]
Closure<R, A1>* NewClosure(T* obj, R(T::*func)(A1)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_1<true, R, T, A1>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)(A1), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_0<true, R, T, A1>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2>* NewClosure(T* obj, R(T::*func)(A1, A2)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_2<true, R, T, A1, A2>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A2>* NewClosure(T* obj, R(T::*func)(A1, A2), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_1<true, R, T, A1, A2>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)(A1, A2), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_0<true, R, T, A1, A2>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3>* NewClosure(T* obj, R(T::*func)(A1, A2, A3)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_3<true, R, T, A1, A2, A3>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3>* NewClosure(T* obj, R(T::*func)(A1, A2, A3), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_2<true, R, T, A1, A2, A3>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A3>* NewClosure(T* obj, R(T::*func)(A1, A2, A3), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_1<true, R, T, A1, A2, A3>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)(A1, A2, A3), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_0<true, R, T, A1, A2, A3>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_4<true, R, T, A1, A2, A3, A4>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_3<true, R, T, A1, A2, A3, A4>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_2<true, R, T, A1, A2, A3, A4>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A4>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_1<true, R, T, A1, A2, A3, A4>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_0<true, R, T, A1, A2, A3, A4>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_5<true, R, T, A1, A2, A3, A4, A5>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_4<true, R, T, A1, A2, A3, A4, A5>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_3<true, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_2<true, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A5>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_1<true, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_5_0<true, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_6<true, R, T, A1, A2, A3, A4, A5, A6>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_5<true, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_4<true, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_3<true, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_2<true, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A6>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_5_1<true, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_6_0<true, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6, A7>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_7<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6, A7>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_6<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6, A7>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_5<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6, A7>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_4<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6, A7>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_3<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A6, A7>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_5_2<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A7>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_6_1<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_7_0<true, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4, a5, a6, a7);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)()) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_0<false, R, T>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1>  // NOLINT [whitespace/line_length]
Closure<R, A1>* NewPermanentClosure(T* obj, R(T::*func)(A1)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_1<false, R, T, A1>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)(A1), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_0<false, R, T, A1>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_2<false, R, T, A1, A2>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A2>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_1<false, R, T, A1, A2>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_0<false, R, T, A1, A2>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_3<false, R, T, A1, A2, A3>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_2<false, R, T, A1, A2, A3>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A3>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_1<false, R, T, A1, A2, A3>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_0<false, R, T, A1, A2, A3>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_4<false, R, T, A1, A2, A3, A4>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_3<false, R, T, A1, A2, A3, A4>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_2<false, R, T, A1, A2, A3, A4>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A4>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_1<false, R, T, A1, A2, A3, A4>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_0<false, R, T, A1, A2, A3, A4>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_5<false, R, T, A1, A2, A3, A4, A5>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_4<false, R, T, A1, A2, A3, A4, A5>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_3<false, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_2<false, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A5>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_1<false, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_5_0<false, R, T, A1, A2, A3, A4, A5>(obj, func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_6<false, R, T, A1, A2, A3, A4, A5, A6>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_5<false, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_4<false, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_3<false, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_2<false, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A6>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_5_1<false, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_6_0<false, R, T, A1, A2, A3, A4, A5, A6>(obj, func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6, A7>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7)) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_0_7<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6, A7>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_1_6<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6, A7>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_2_5<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6, A7>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_3_4<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6, A7>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_4_3<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A6, A7>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_5_2<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A7>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_6_1<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename T, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(T* obj, R(T::*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {  // NOLINT [whitespace/line_length]
  return new closure::MethodClosure_7_0<false, R, T, A1, A2, A3, A4, A5, A6, A7>(obj, func, a1, a2, a3, a4, a5, a6, a7);  // NOLINT [whitespace/line_length]
}

template<typename R>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)()) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_0<true, R>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1>  // NOLINT [whitespace/line_length]
Closure<R, A1>* NewClosure(R(*func)(A1)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_1<true, R, A1>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)(A1), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_0<true, R, A1>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2>* NewClosure(R(*func)(A1, A2)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_2<true, R, A1, A2>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A2>* NewClosure(R(*func)(A1, A2), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_1<true, R, A1, A2>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)(A1, A2), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_0<true, R, A1, A2>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3>* NewClosure(R(*func)(A1, A2, A3)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_3<true, R, A1, A2, A3>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3>* NewClosure(R(*func)(A1, A2, A3), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_2<true, R, A1, A2, A3>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A3>* NewClosure(R(*func)(A1, A2, A3), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_1<true, R, A1, A2, A3>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)(A1, A2, A3), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_0<true, R, A1, A2, A3>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4>* NewClosure(R(*func)(A1, A2, A3, A4)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_4<true, R, A1, A2, A3, A4>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4>* NewClosure(R(*func)(A1, A2, A3, A4), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_3<true, R, A1, A2, A3, A4>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4>* NewClosure(R(*func)(A1, A2, A3, A4), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_2<true, R, A1, A2, A3, A4>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A4>* NewClosure(R(*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_1<true, R, A1, A2, A3, A4>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_0<true, R, A1, A2, A3, A4>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5>* NewClosure(R(*func)(A1, A2, A3, A4, A5)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_5<true, R, A1, A2, A3, A4, A5>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5>* NewClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_4<true, R, A1, A2, A3, A4, A5>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5>* NewClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_3<true, R, A1, A2, A3, A4, A5>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5>* NewClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_2<true, R, A1, A2, A3, A4, A5>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A5>* NewClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_1<true, R, A1, A2, A3, A4, A5>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_5_0<true, R, A1, A2, A3, A4, A5>(func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_6<true, R, A1, A2, A3, A4, A5, A6>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_5<true, R, A1, A2, A3, A4, A5, A6>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_4<true, R, A1, A2, A3, A4, A5, A6>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_3<true, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_2<true, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A6>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_5_1<true, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_6_0<true, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6, A7>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_7<true, R, A1, A2, A3, A4, A5, A6, A7>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6, A7>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_6<true, R, A1, A2, A3, A4, A5, A6, A7>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6, A7>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_5<true, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6, A7>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_4<true, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6, A7>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_3<true, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A6, A7>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_5_2<true, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A7>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_6_1<true, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R>* NewClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_7_0<true, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4, a5, a6, a7);  // NOLINT [whitespace/line_length]
}

template<typename R>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)()) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_0<false, R>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1>  // NOLINT [whitespace/line_length]
Closure<R, A1>* NewPermanentClosure(R(*func)(A1)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_1<false, R, A1>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)(A1), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_0<false, R, A1>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2>* NewPermanentClosure(R(*func)(A1, A2)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_2<false, R, A1, A2>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R, A2>* NewPermanentClosure(R(*func)(A1, A2), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_1<false, R, A1, A2>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)(A1, A2), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_0<false, R, A1, A2>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3>* NewPermanentClosure(R(*func)(A1, A2, A3)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_3<false, R, A1, A2, A3>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3>* NewPermanentClosure(R(*func)(A1, A2, A3), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_2<false, R, A1, A2, A3>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R, A3>* NewPermanentClosure(R(*func)(A1, A2, A3), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_1<false, R, A1, A2, A3>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)(A1, A2, A3), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_0<false, R, A1, A2, A3>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4>* NewPermanentClosure(R(*func)(A1, A2, A3, A4)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_4<false, R, A1, A2, A3, A4>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4>* NewPermanentClosure(R(*func)(A1, A2, A3, A4), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_3<false, R, A1, A2, A3, A4>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4>* NewPermanentClosure(R(*func)(A1, A2, A3, A4), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_2<false, R, A1, A2, A3, A4>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R, A4>* NewPermanentClosure(R(*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_1<false, R, A1, A2, A3, A4>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_0<false, R, A1, A2, A3, A4>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_5<false, R, A1, A2, A3, A4, A5>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_4<false, R, A1, A2, A3, A4, A5>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_3<false, R, A1, A2, A3, A4, A5>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_2<false, R, A1, A2, A3, A4, A5>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R, A5>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_1<false, R, A1, A2, A3, A4, A5>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_5_0<false, R, A1, A2, A3, A4, A5>(func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_6<false, R, A1, A2, A3, A4, A5, A6>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_5<false, R, A1, A2, A3, A4, A5, A6>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_4<false, R, A1, A2, A3, A4, A5, A6>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_3<false, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_2<false, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R, A6>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_5_1<false, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_6_0<false, R, A1, A2, A3, A4, A5, A6>(func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A1, A2, A3, A4, A5, A6, A7>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7)) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_0_7<false, R, A1, A2, A3, A4, A5, A6, A7>(func);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A2, A3, A4, A5, A6, A7>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_1_6<false, R, A1, A2, A3, A4, A5, A6, A7>(func, a1);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A3, A4, A5, A6, A7>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_2_5<false, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A4, A5, A6, A7>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_3_4<false, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A5, A6, A7>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_4_3<false, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A6, A7>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_5_2<false, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4, a5);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R, A7>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_6_1<false, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4, a5, a6);  // NOLINT [whitespace/line_length]
}

template<typename R, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>  // NOLINT [whitespace/line_length]
Closure<R>* NewPermanentClosure(R(*func)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {  // NOLINT [whitespace/line_length]
  return new closure::FunctionClosure_7_0<false, R, A1, A2, A3, A4, A5, A6, A7>(func, a1, a2, a3, a4, a5, a6, a7);  // NOLINT [whitespace/line_length]
}

}  // namespace graphlearn

#endif  // GRAPHLEARN_COMMON_BASE_CLOSURE_H_
