Rewrite rtc::Bind using variadic templates.

I'd like to make a change to rtc::Bind in another CL, and that will
be easier if there are fewer lines of code to modify.

BUG=None

Review-Url: https://codereview.webrtc.org/2719683002
Cr-Original-Commit-Position: refs/heads/master@{#16838}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 08187d41ca45e4671e41856785590d2408c129b6
diff --git a/base/bind.h b/base/bind.h
index e8c1ab5..397a4d5 100644
--- a/base/bind.h
+++ b/base/bind.h
@@ -1,7 +1,3 @@
-// This file was GENERATED by command:
-//     pump.py bind.h.pump
-// DO NOT EDIT BY HAND!!!
-
 /*
  *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
  *
@@ -12,9 +8,6 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-// To generate bind.h from bind.h.pump, execute:
-// /home/build/google3/third_party/gtest/scripts/pump.py bind.h.pump
-
 // Bind() is an overloaded function that converts method calls into function
 // objects (aka functors). The method object is captured as a scoped_refptr<> if
 // possible, and as a raw pointer otherwise. Any arguments to the method are
@@ -64,6 +57,9 @@
 #ifndef WEBRTC_BASE_BIND_H_
 #define WEBRTC_BASE_BIND_H_
 
+#include <tuple>
+#include <type_traits>
+
 #include "webrtc/base/scoped_ref_ptr.h"
 #include "webrtc/base/template_util.h"
 
@@ -131,1406 +127,94 @@
 
 }  // namespace detail
 
-template <class ObjectT, class MethodT, class R>
-class MethodFunctor0 {
+template <class ObjectT, class MethodT, class R, typename... Args>
+class MethodFunctor {
  public:
-  MethodFunctor0(MethodT method, ObjectT* object)
-      : method_(method), object_(object) {}
+  MethodFunctor(MethodT method, ObjectT* object, Args... args)
+      : method_(method), object_(object), args_(args...) {}
   R operator()() const {
-    return (object_->*method_)(); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-};
-
-template <class FunctorT, class R>
-class Functor0 {
- public:
-  explicit Functor0(const FunctorT& functor)
-      : functor_(functor) {}
-  R operator()() const {
-    return functor_(); }
- private:
-  FunctorT functor_;
-};
-
-
-#define FP_T(x) R (ObjectT::*x)()
-
-template <class ObjectT, class R>
-MethodFunctor0<ObjectT, FP_T(NONAME), R>
-Bind(FP_T(method), ObjectT* object) {
-  return MethodFunctor0<ObjectT, FP_T(NONAME), R>(
-      method, object);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)() const
-
-template <class ObjectT, class R>
-MethodFunctor0<const ObjectT, FP_T(NONAME), R>
-Bind(FP_T(method), const ObjectT* object) {
-  return MethodFunctor0<const ObjectT, FP_T(NONAME), R>(
-      method, object);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)()
-
-template <class ObjectT, class R>
-MethodFunctor0<ObjectT, FP_T(NONAME), R>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object) {
-  return MethodFunctor0<ObjectT, FP_T(NONAME), R>(
-      method, object.get());
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)()
-
-template <class R>
-Functor0<FP_T(NONAME), R>
-Bind(FP_T(function)) {
-  return Functor0<FP_T(NONAME), R>(
-      function);
-}
-
-#undef FP_T
-
-template <class ObjectT, class MethodT, class R,
-          class P1>
-class MethodFunctor1 {
- public:
-  MethodFunctor1(MethodT method, ObjectT* object,
-                 P1 p1)
-      : method_(method), object_(object),
-      p1_(p1) {}
-  R operator()() const {
-    return (object_->*method_)(p1_); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-};
-
-template <class FunctorT, class R,
-          class P1>
-class Functor1 {
- public:
-  Functor1(const FunctorT& functor, P1 p1)
-      : functor_(functor),
-      p1_(p1) {}
-  R operator()() const {
-    return functor_(p1_); }
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-};
-
-
-#define FP_T(x) R (ObjectT::*x)(P1)
-
-template <class ObjectT, class R,
-          class P1>
-MethodFunctor1<ObjectT, FP_T(NONAME), R, P1>
-Bind(FP_T(method), ObjectT* object,
-     typename detail::identity<P1>::type p1) {
-  return MethodFunctor1<ObjectT, FP_T(NONAME), R, P1>(
-      method, object, p1);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1) const
-
-template <class ObjectT, class R,
-          class P1>
-MethodFunctor1<const ObjectT, FP_T(NONAME), R, P1>
-Bind(FP_T(method), const ObjectT* object,
-     typename detail::identity<P1>::type p1) {
-  return MethodFunctor1<const ObjectT, FP_T(NONAME), R, P1>(
-      method, object, p1);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1)
-
-template <class ObjectT, class R,
-          class P1>
-MethodFunctor1<ObjectT, FP_T(NONAME), R, P1>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object,
-     typename detail::identity<P1>::type p1) {
-  return MethodFunctor1<ObjectT, FP_T(NONAME), R, P1>(
-      method, object.get(), p1);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1)
-
-template <class R,
-          class P1>
-Functor1<FP_T(NONAME), R, P1>
-Bind(FP_T(function),
-     typename detail::identity<P1>::type p1) {
-  return Functor1<FP_T(NONAME), R, P1>(
-      function, p1);
-}
-
-#undef FP_T
-
-template <class ObjectT, class MethodT, class R,
-          class P1,
-          class P2>
-class MethodFunctor2 {
- public:
-  MethodFunctor2(MethodT method, ObjectT* object,
-                 P1 p1,
-                 P2 p2)
-      : method_(method), object_(object),
-      p1_(p1),
-      p2_(p2) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-};
-
-template <class FunctorT, class R,
-          class P1,
-          class P2>
-class Functor2 {
- public:
-  Functor2(const FunctorT& functor, P1 p1, P2 p2)
-      : functor_(functor),
-      p1_(p1),
-      p2_(p2) {}
-  R operator()() const {
-    return functor_(p1_, p2_); }
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-};
-
-
-#define FP_T(x) R (ObjectT::*x)(P1, P2)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2>
-MethodFunctor2<ObjectT, FP_T(NONAME), R, P1, P2>
-Bind(FP_T(method), ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2) {
-  return MethodFunctor2<ObjectT, FP_T(NONAME), R, P1, P2>(
-      method, object, p1, p2);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2) const
-
-template <class ObjectT, class R,
-          class P1,
-          class P2>
-MethodFunctor2<const ObjectT, FP_T(NONAME), R, P1, P2>
-Bind(FP_T(method), const ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2) {
-  return MethodFunctor2<const ObjectT, FP_T(NONAME), R, P1, P2>(
-      method, object, p1, p2);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2>
-MethodFunctor2<ObjectT, FP_T(NONAME), R, P1, P2>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2) {
-  return MethodFunctor2<ObjectT, FP_T(NONAME), R, P1, P2>(
-      method, object.get(), p1, p2);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1, P2)
-
-template <class R,
-          class P1,
-          class P2>
-Functor2<FP_T(NONAME), R, P1, P2>
-Bind(FP_T(function),
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2) {
-  return Functor2<FP_T(NONAME), R, P1, P2>(
-      function, p1, p2);
-}
-
-#undef FP_T
-
-template <class ObjectT, class MethodT, class R,
-          class P1,
-          class P2,
-          class P3>
-class MethodFunctor3 {
- public:
-  MethodFunctor3(MethodT method, ObjectT* object,
-                 P1 p1,
-                 P2 p2,
-                 P3 p3)
-      : method_(method), object_(object),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_, p3_); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-};
-
-template <class FunctorT, class R,
-          class P1,
-          class P2,
-          class P3>
-class Functor3 {
- public:
-  Functor3(const FunctorT& functor, P1 p1, P2 p2, P3 p3)
-      : functor_(functor),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3) {}
-  R operator()() const {
-    return functor_(p1_, p2_, p3_); }
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-};
-
-
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3>
-MethodFunctor3<ObjectT, FP_T(NONAME), R, P1, P2, P3>
-Bind(FP_T(method), ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3) {
-  return MethodFunctor3<ObjectT, FP_T(NONAME), R, P1, P2, P3>(
-      method, object, p1, p2, p3);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3) const
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3>
-MethodFunctor3<const ObjectT, FP_T(NONAME), R, P1, P2, P3>
-Bind(FP_T(method), const ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3) {
-  return MethodFunctor3<const ObjectT, FP_T(NONAME), R, P1, P2, P3>(
-      method, object, p1, p2, p3);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3>
-MethodFunctor3<ObjectT, FP_T(NONAME), R, P1, P2, P3>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3) {
-  return MethodFunctor3<ObjectT, FP_T(NONAME), R, P1, P2, P3>(
-      method, object.get(), p1, p2, p3);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1, P2, P3)
-
-template <class R,
-          class P1,
-          class P2,
-          class P3>
-Functor3<FP_T(NONAME), R, P1, P2, P3>
-Bind(FP_T(function),
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3) {
-  return Functor3<FP_T(NONAME), R, P1, P2, P3>(
-      function, p1, p2, p3);
-}
-
-#undef FP_T
-
-template <class ObjectT, class MethodT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4>
-class MethodFunctor4 {
- public:
-  MethodFunctor4(MethodT method, ObjectT* object,
-                 P1 p1,
-                 P2 p2,
-                 P3 p3,
-                 P4 p4)
-      : method_(method), object_(object),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3),
-      p4_(p4) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_, p3_, p4_); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-};
-
-template <class FunctorT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4>
-class Functor4 {
- public:
-  Functor4(const FunctorT& functor, P1 p1, P2 p2, P3 p3, P4 p4)
-      : functor_(functor),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3),
-      p4_(p4) {}
-  R operator()() const {
-    return functor_(p1_, p2_, p3_, p4_); }
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-};
-
-
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4>
-MethodFunctor4<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>
-Bind(FP_T(method), ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4) {
-  return MethodFunctor4<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>(
-      method, object, p1, p2, p3, p4);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4) const
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4>
-MethodFunctor4<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>
-Bind(FP_T(method), const ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4) {
-  return MethodFunctor4<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>(
-      method, object, p1, p2, p3, p4);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4>
-MethodFunctor4<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4) {
-  return MethodFunctor4<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4>(
-      method, object.get(), p1, p2, p3, p4);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1, P2, P3, P4)
-
-template <class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4>
-Functor4<FP_T(NONAME), R, P1, P2, P3, P4>
-Bind(FP_T(function),
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4) {
-  return Functor4<FP_T(NONAME), R, P1, P2, P3, P4>(
-      function, p1, p2, p3, p4);
-}
-
-#undef FP_T
-
-template <class ObjectT, class MethodT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5>
-class MethodFunctor5 {
- public:
-  MethodFunctor5(MethodT method, ObjectT* object,
-                 P1 p1,
-                 P2 p2,
-                 P3 p3,
-                 P4 p4,
-                 P5 p5)
-      : method_(method), object_(object),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3),
-      p4_(p4),
-      p5_(p5) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_, p3_, p4_, p5_); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-};
-
-template <class FunctorT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5>
-class Functor5 {
- public:
-  Functor5(const FunctorT& functor, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
-      : functor_(functor),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3),
-      p4_(p4),
-      p5_(p5) {}
-  R operator()() const {
-    return functor_(p1_, p2_, p3_, p4_, p5_); }
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-};
-
-
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5>
-MethodFunctor5<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>
-Bind(FP_T(method), ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5) {
-  return MethodFunctor5<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>(
-      method, object, p1, p2, p3, p4, p5);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5) const
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5>
-MethodFunctor5<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>
-Bind(FP_T(method), const ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5) {
-  return MethodFunctor5<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>(
-      method, object, p1, p2, p3, p4, p5);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5>
-MethodFunctor5<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5) {
-  return MethodFunctor5<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5>(
-      method, object.get(), p1, p2, p3, p4, p5);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1, P2, P3, P4, P5)
-
-template <class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5>
-Functor5<FP_T(NONAME), R, P1, P2, P3, P4, P5>
-Bind(FP_T(function),
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5) {
-  return Functor5<FP_T(NONAME), R, P1, P2, P3, P4, P5>(
-      function, p1, p2, p3, p4, p5);
-}
-
-#undef FP_T
-
-template <class ObjectT, class MethodT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6>
-class MethodFunctor6 {
- public:
-  MethodFunctor6(MethodT method, ObjectT* object,
-                 P1 p1,
-                 P2 p2,
-                 P3 p3,
-                 P4 p4,
-                 P5 p5,
-                 P6 p6)
-      : method_(method), object_(object),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3),
-      p4_(p4),
-      p5_(p5),
-      p6_(p6) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-};
-
-template <class FunctorT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6>
-class Functor6 {
- public:
-  Functor6(const FunctorT& functor, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
-      : functor_(functor),
-      p1_(p1),
-      p2_(p2),
-      p3_(p3),
-      p4_(p4),
-      p5_(p5),
-      p6_(p6) {}
-  R operator()() const {
-    return functor_(p1_, p2_, p3_, p4_, p5_, p6_); }
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-};
-
-
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6>
-MethodFunctor6<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>
-Bind(FP_T(method), ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6) {
-  return MethodFunctor6<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>(
-      method, object, p1, p2, p3, p4, p5, p6);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6) const
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6>
-MethodFunctor6<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>
-Bind(FP_T(method), const ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6) {
-  return MethodFunctor6<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>(
-      method, object, p1, p2, p3, p4, p5, p6);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6)
-
-template <class ObjectT, class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6>
-MethodFunctor6<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6) {
-  return MethodFunctor6<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>(
-      method, object.get(), p1, p2, p3, p4, p5, p6);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1, P2, P3, P4, P5, P6)
-
-template <class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6>
-Functor6<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>
-Bind(FP_T(function),
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6) {
-  return Functor6<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6>(
-      function, p1, p2, p3, p4, p5, p6);
-}
-
-#undef FP_T
-
-template <class ObjectT,
-          class MethodT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7>
-class MethodFunctor7 {
- public:
-  MethodFunctor7(MethodT method,
-                 ObjectT* object,
-                 P1 p1,
-                 P2 p2,
-                 P3 p3,
-                 P4 p4,
-                 P5 p5,
-                 P6 p6,
-                 P7 p7)
-      : method_(method),
-        object_(object),
-        p1_(p1),
-        p2_(p2),
-        p3_(p3),
-        p4_(p4),
-        p5_(p5),
-        p6_(p6),
-        p7_(p7) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_, p7_);
+    return CallMethod(typename sequence_generator<sizeof...(Args)>::type());
   }
 
  private:
+  // Use sequence_generator (see template_util.h) to expand a MethodFunctor
+  // with 2 arguments to (std::get<0>(args_), std::get<1>(args_)), for
+  // instance.
+  template <int... S>
+  R CallMethod(sequence<S...>) const {
+    return (object_->*method_)(std::get<S>(args_)...);
+  }
+
   MethodT method_;
   typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-  typename rtc::remove_reference<P7>::type p7_;
+  typename std::tuple<typename std::remove_reference<Args>::type...> args_;
 };
 
-template <class FunctorT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7>
-class Functor7 {
+template <class FunctorT, class R, typename... Args>
+class Functor {
  public:
-  Functor7(const FunctorT& functor,
-           P1 p1,
-           P2 p2,
-           P3 p3,
-           P4 p4,
-           P5 p5,
-           P6 p6,
-           P7 p7)
-      : functor_(functor),
-        p1_(p1),
-        p2_(p2),
-        p3_(p3),
-        p4_(p4),
-        p5_(p5),
-        p6_(p6),
-        p7_(p7) {}
-  R operator()() const { return functor_(p1_, p2_, p3_, p4_, p5_, p6_, p7_); }
+  Functor(const FunctorT& functor, Args... args)
+      : functor_(functor), args_(args...) {}
+  R operator()() const {
+    return CallFunction(typename sequence_generator<sizeof...(Args)>::type());
+  }
 
  private:
+  // Use sequence_generator (see template_util.h) to expand a Functor
+  // with 2 arguments to (std::get<0>(args_), std::get<1>(args_)), for
+  // instance.
+  template <int... S>
+  R CallFunction(sequence<S...>) const {
+    return functor_(std::get<S>(args_)...);
+  }
+
   FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-  typename rtc::remove_reference<P7>::type p7_;
+  typename std::tuple<typename std::remove_reference<Args>::type...> args_;
 };
 
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7)
+#define FP_T(x) R (ObjectT::*x)(Args...)
 
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7>
-MethodFunctor7<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7> Bind(
+template <class ObjectT, class R, typename... Args>
+MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
     FP_T(method),
     ObjectT* object,
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7) {
-  return MethodFunctor7<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7>(
-      method, object, p1, p2, p3, p4, p5, p6, p7);
+    typename detail::identity<Args>::type... args) {
+  return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object,
+                                                          args...);
 }
 
 #undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7) const
+#define FP_T(x) R (ObjectT::*x)(Args...) const
 
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7>
-MethodFunctor7<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7> Bind(
+template <class ObjectT, class R, typename... Args>
+MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...> Bind(
     FP_T(method),
     const ObjectT* object,
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7) {
-  return MethodFunctor7<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6,
-                        P7>(method, object, p1, p2, p3, p4, p5, p6, p7);
+    typename detail::identity<Args>::type... args) {
+  return MethodFunctor<const ObjectT, FP_T(NONAME), R, Args...>(method, object,
+                                                                args...);
 }
 
 #undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7)
+#define FP_T(x) R (ObjectT::*x)(Args...)
 
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7>
-MethodFunctor7<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7> Bind(
+template <class ObjectT, class R, typename... Args>
+MethodFunctor<ObjectT, FP_T(NONAME), R, Args...> Bind(
     FP_T(method),
     const scoped_refptr<ObjectT>& object,
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7) {
-  return MethodFunctor7<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7>(
-      method, object.get(), p1, p2, p3, p4, p5, p6, p7);
+    typename detail::identity<Args>::type... args) {
+  return MethodFunctor<ObjectT, FP_T(NONAME), R, Args...>(method, object.get(),
+                                                          args...);
 }
 
 #undef FP_T
-#define FP_T(x) R (*x)(P1, P2, P3, P4, P5, P6, P7)
+#define FP_T(x) R (*x)(Args...)
 
-template <class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7>
-Functor7<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7> Bind(
+template <class R, typename... Args>
+Functor<FP_T(NONAME), R, Args...> Bind(
     FP_T(function),
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7) {
-  return Functor7<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7>(
-      function, p1, p2, p3, p4, p5, p6, p7);
-}
-
-#undef FP_T
-
-template <class ObjectT,
-          class MethodT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8>
-class MethodFunctor8 {
- public:
-  MethodFunctor8(MethodT method,
-                 ObjectT* object,
-                 P1 p1,
-                 P2 p2,
-                 P3 p3,
-                 P4 p4,
-                 P5 p5,
-                 P6 p6,
-                 P7 p7,
-                 P8 p8)
-      : method_(method),
-        object_(object),
-        p1_(p1),
-        p2_(p2),
-        p3_(p3),
-        p4_(p4),
-        p5_(p5),
-        p6_(p6),
-        p7_(p7),
-        p8_(p8) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_);
-  }
-
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-  typename rtc::remove_reference<P7>::type p7_;
-  typename rtc::remove_reference<P8>::type p8_;
-};
-
-template <class FunctorT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8>
-class Functor8 {
- public:
-  Functor8(const FunctorT& functor,
-           P1 p1,
-           P2 p2,
-           P3 p3,
-           P4 p4,
-           P5 p5,
-           P6 p6,
-           P7 p7,
-           P8 p8)
-      : functor_(functor),
-        p1_(p1),
-        p2_(p2),
-        p3_(p3),
-        p4_(p4),
-        p5_(p5),
-        p6_(p6),
-        p7_(p7),
-        p8_(p8) {}
-  R operator()() const {
-    return functor_(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_);
-  }
-
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-  typename rtc::remove_reference<P7>::type p7_;
-  typename rtc::remove_reference<P8>::type p8_;
-};
-
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8)
-
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8>
-MethodFunctor8<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8> Bind(
-    FP_T(method),
-    ObjectT* object,
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7,
-    typename detail::identity<P8>::type p8) {
-  return MethodFunctor8<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7,
-                        P8>(method, object, p1, p2, p3, p4, p5, p6, p7, p8);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8) const
-
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8>
-MethodFunctor8<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8>
-Bind(FP_T(method),
-     const ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6,
-     typename detail::identity<P7>::type p7,
-     typename detail::identity<P8>::type p8) {
-  return MethodFunctor8<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6,
-                        P7, P8>(method, object, p1, p2, p3, p4, p5, p6, p7, p8);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8)
-
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8>
-MethodFunctor8<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8> Bind(
-    FP_T(method),
-    const scoped_refptr<ObjectT>& object,
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7,
-    typename detail::identity<P8>::type p8) {
-  return MethodFunctor8<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7,
-                        P8>(method, object.get(), p1, p2, p3, p4, p5, p6, p7,
-                            p8);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1, P2, P3, P4, P5, P6, P7, P8)
-
-template <class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8>
-Functor8<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8> Bind(
-    FP_T(function),
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7,
-    typename detail::identity<P8>::type p8) {
-  return Functor8<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8>(
-      function, p1, p2, p3, p4, p5, p6, p7, p8);
-}
-
-#undef FP_T
-
-template <class ObjectT,
-          class MethodT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8,
-          class P9>
-class MethodFunctor9 {
- public:
-  MethodFunctor9(MethodT method,
-                 ObjectT* object,
-                 P1 p1,
-                 P2 p2,
-                 P3 p3,
-                 P4 p4,
-                 P5 p5,
-                 P6 p6,
-                 P7 p7,
-                 P8 p8,
-                 P9 p9)
-      : method_(method),
-        object_(object),
-        p1_(p1),
-        p2_(p2),
-        p3_(p3),
-        p4_(p4),
-        p5_(p5),
-        p6_(p6),
-        p7_(p7),
-        p8_(p8),
-        p9_(p9) {}
-  R operator()() const {
-    return (object_->*method_)(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_, p9_);
-  }
-
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-  typename rtc::remove_reference<P7>::type p7_;
-  typename rtc::remove_reference<P8>::type p8_;
-  typename rtc::remove_reference<P9>::type p9_;
-};
-
-template <class FunctorT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8,
-          class P9>
-class Functor9 {
- public:
-  Functor9(const FunctorT& functor,
-           P1 p1,
-           P2 p2,
-           P3 p3,
-           P4 p4,
-           P5 p5,
-           P6 p6,
-           P7 p7,
-           P8 p8,
-           P9 p9)
-      : functor_(functor),
-        p1_(p1),
-        p2_(p2),
-        p3_(p3),
-        p4_(p4),
-        p5_(p5),
-        p6_(p6),
-        p7_(p7),
-        p8_(p8),
-        p9_(p9) {}
-  R operator()() const {
-    return functor_(p1_, p2_, p3_, p4_, p5_, p6_, p7_, p8_, p9_);
-  }
-
- private:
-  FunctorT functor_;
-  typename rtc::remove_reference<P1>::type p1_;
-  typename rtc::remove_reference<P2>::type p2_;
-  typename rtc::remove_reference<P3>::type p3_;
-  typename rtc::remove_reference<P4>::type p4_;
-  typename rtc::remove_reference<P5>::type p5_;
-  typename rtc::remove_reference<P6>::type p6_;
-  typename rtc::remove_reference<P7>::type p7_;
-  typename rtc::remove_reference<P8>::type p8_;
-  typename rtc::remove_reference<P9>::type p9_;
-};
-
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9)
-
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8,
-          class P9>
-MethodFunctor9<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8, P9>
-Bind(FP_T(method),
-     ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6,
-     typename detail::identity<P7>::type p7,
-     typename detail::identity<P8>::type p8,
-     typename detail::identity<P9>::type p9) {
-  return MethodFunctor9<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7,
-                        P8, P9>(method, object, p1, p2, p3, p4, p5, p6, p7, p8,
-                                p9);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9) const
-
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8,
-          class P9>
-MethodFunctor9<const ObjectT,
-               FP_T(NONAME),
-               R,
-               P1,
-               P2,
-               P3,
-               P4,
-               P5,
-               P6,
-               P7,
-               P8,
-               P9>
-Bind(FP_T(method),
-     const ObjectT* object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6,
-     typename detail::identity<P7>::type p7,
-     typename detail::identity<P8>::type p8,
-     typename detail::identity<P9>::type p9) {
-  return MethodFunctor9<const ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6,
-                        P7, P8, P9>(method, object, p1, p2, p3, p4, p5, p6, p7,
-                                    p8, p9);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9)
-
-template <class ObjectT,
-          class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8,
-          class P9>
-MethodFunctor9<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8, P9>
-Bind(FP_T(method),
-     const scoped_refptr<ObjectT>& object,
-     typename detail::identity<P1>::type p1,
-     typename detail::identity<P2>::type p2,
-     typename detail::identity<P3>::type p3,
-     typename detail::identity<P4>::type p4,
-     typename detail::identity<P5>::type p5,
-     typename detail::identity<P6>::type p6,
-     typename detail::identity<P7>::type p7,
-     typename detail::identity<P8>::type p8,
-     typename detail::identity<P9>::type p9) {
-  return MethodFunctor9<ObjectT, FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7,
-                        P8, P9>(method, object.get(), p1, p2, p3, p4, p5, p6,
-                                p7, p8, p9);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)(P1, P2, P3, P4, P5, P6, P7, P8, P9)
-
-template <class R,
-          class P1,
-          class P2,
-          class P3,
-          class P4,
-          class P5,
-          class P6,
-          class P7,
-          class P8,
-          class P9>
-Functor9<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8, P9> Bind(
-    FP_T(function),
-    typename detail::identity<P1>::type p1,
-    typename detail::identity<P2>::type p2,
-    typename detail::identity<P3>::type p3,
-    typename detail::identity<P4>::type p4,
-    typename detail::identity<P5>::type p5,
-    typename detail::identity<P6>::type p6,
-    typename detail::identity<P7>::type p7,
-    typename detail::identity<P8>::type p8,
-    typename detail::identity<P9>::type p9) {
-  return Functor9<FP_T(NONAME), R, P1, P2, P3, P4, P5, P6, P7, P8, P9>(
-      function, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+    typename detail::identity<Args>::type... args) {
+  return Functor<FP_T(NONAME), R, Args...>(function, args...);
 }
 
 #undef FP_T
diff --git a/base/bind.h.pump b/base/bind.h.pump
deleted file mode 100644
index 2a1a55c..0000000
--- a/base/bind.h.pump
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-// To generate bind.h from bind.h.pump, execute:
-// /home/build/google3/third_party/gtest/scripts/pump.py bind.h.pump
-
-// Bind() is an overloaded function that converts method calls into function
-// objects (aka functors). The method object is captured as a scoped_refptr<> if
-// possible, and as a raw pointer otherwise. Any arguments to the method are
-// captured by value. The return value of Bind is a stateful, nullary function
-// object. Care should be taken about the lifetime of objects captured by
-// Bind(); the returned functor knows nothing about the lifetime of a non
-// ref-counted method object or any arguments passed by pointer, and calling the
-// functor with a destroyed object will surely do bad things.
-//
-// Example usage:
-//   struct Foo {
-//     int Test1() { return 42; }
-//     int Test2() const { return 52; }
-//     int Test3(int x) { return x*x; }
-//     float Test4(int x, float y) { return x + y; }
-//   };
-//
-//   int main() {
-//     Foo foo;
-//     cout << rtc::Bind(&Foo::Test1, &foo)() << endl;
-//     cout << rtc::Bind(&Foo::Test2, &foo)() << endl;
-//     cout << rtc::Bind(&Foo::Test3, &foo, 3)() << endl;
-//     cout << rtc::Bind(&Foo::Test4, &foo, 7, 8.5f)() << endl;
-//   }
-//
-// Example usage of ref counted objects:
-//   struct Bar {
-//     int AddRef();
-//     int Release();
-//
-//     void Test() {}
-//     void BindThis() {
-//       // The functor passed to AsyncInvoke() will keep this object alive.
-//       invoker.AsyncInvoke(RTC_FROM_HERE,rtc::Bind(&Bar::Test, this));
-//     }
-//   };
-//
-//   int main() {
-//     rtc::scoped_refptr<Bar> bar = new rtc::RefCountedObject<Bar>();
-//     auto functor = rtc::Bind(&Bar::Test, bar);
-//     bar = nullptr;
-//     // The functor stores an internal scoped_refptr<Bar>, so this is safe.
-//     functor();
-//   }
-//
-
-#ifndef WEBRTC_BASE_BIND_H_
-#define WEBRTC_BASE_BIND_H_
-
-#include "webrtc/base/scoped_ref_ptr.h"
-#include "webrtc/base/template_util.h"
-
-#define NONAME
-
-namespace rtc {
-namespace detail {
-// This is needed because the template parameters in Bind can't be resolved
-// if they're used both as parameters of the function pointer type and as
-// parameters to Bind itself: the function pointer parameters are exact
-// matches to the function prototype, but the parameters to bind have
-// references stripped. This trick allows the compiler to dictate the Bind
-// parameter types rather than deduce them.
-template <class T> struct identity { typedef T type; };
-
-// IsRefCounted<T>::value will be true for types that can be used in
-// rtc::scoped_refptr<T>, i.e. types that implements nullary functions AddRef()
-// and Release(), regardless of their return types. AddRef() and Release() can
-// be defined in T or any superclass of T.
-template <typename T>
-class IsRefCounted {
-  // This is a complex implementation detail done with SFINAE.
-
-  // Define types such that sizeof(Yes) != sizeof(No).
-  struct Yes { char dummy[1]; };
-  struct No { char dummy[2]; };
-  // Define two overloaded template functions with return types of different
-  // size. This way, we can use sizeof() on the return type to determine which
-  // function the compiler would have chosen. One function will be preferred
-  // over the other if it is possible to create it without compiler errors,
-  // otherwise the compiler will simply remove it, and default to the less
-  // preferred function.
-  template <typename R>
-  static Yes test(R* r, decltype(r->AddRef(), r->Release(), 42));
-  template <typename C> static No test(...);
-
-public:
-  // Trick the compiler to tell if it's possible to call AddRef() and Release().
-  static const bool value = sizeof(test<T>((T*)nullptr, 42)) == sizeof(Yes);
-};
-
-// TernaryTypeOperator is a helper class to select a type based on a static bool
-// value.
-template <bool condition, typename IfTrueT, typename IfFalseT>
-struct TernaryTypeOperator {};
-
-template <typename IfTrueT, typename IfFalseT>
-struct TernaryTypeOperator<true, IfTrueT, IfFalseT> {
-  typedef IfTrueT type;
-};
-
-template <typename IfTrueT, typename IfFalseT>
-struct TernaryTypeOperator<false, IfTrueT, IfFalseT> {
-  typedef IfFalseT type;
-};
-
-// PointerType<T>::type will be scoped_refptr<T> for ref counted types, and T*
-// otherwise.
-template <class T>
-struct PointerType {
-  typedef typename TernaryTypeOperator<IsRefCounted<T>::value,
-                                       scoped_refptr<T>,
-                                       T*>::type type;
-};
-
-}  // namespace detail
-
-$var n = 9
-$range i 0..n
-$for i [[
-$range j 1..i
-
-template <class ObjectT, class MethodT, class R$for j [[,
-          class P$j]]>
-class MethodFunctor$i {
- public:
-  MethodFunctor$i(MethodT method, ObjectT* object$for j [[,
-                 P$j p$j]])
-      : method_(method), object_(object)$for j [[,
-      p$(j)_(p$j)]] {}
-  R operator()() const {
-    return (object_->*method_)($for j , [[p$(j)_]]); }
- private:
-  MethodT method_;
-  typename detail::PointerType<ObjectT>::type object_;$for j [[
-
-  typename rtc::remove_reference<P$j>::type p$(j)_;]]
-
-};
-
-template <class FunctorT, class R$for j [[,
-          class P$j]]>
-class Functor$i {
- public:
-  $if i == 0 [[explicit ]]
-Functor$i(const FunctorT& functor$for j [[, P$j p$j]])
-      : functor_(functor)$for j [[,
-      p$(j)_(p$j)]] {}
-  R operator()() const {
-    return functor_($for j , [[p$(j)_]]); }
- private:
-  FunctorT functor_;$for j [[
-
-  typename rtc::remove_reference<P$j>::type p$(j)_;]]
-
-};
-
-
-#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]])
-
-template <class ObjectT, class R$for j [[,
-          class P$j]]>
-MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>
-Bind(FP_T(method), ObjectT* object$for j [[,
-     typename detail::identity<P$j>::type p$j]]) {
-  return MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>(
-      method, object$for j [[, p$j]]);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]]) const
-
-template <class ObjectT, class R$for j [[,
-          class P$j]]>
-MethodFunctor$i<const ObjectT, FP_T(NONAME), R$for j [[, P$j]]>
-Bind(FP_T(method), const ObjectT* object$for j [[,
-     typename detail::identity<P$j>::type p$j]]) {
-  return MethodFunctor$i<const ObjectT, FP_T(NONAME), R$for j [[, P$j]]>(
-      method, object$for j [[, p$j]]);
-}
-
-#undef FP_T
-#define FP_T(x) R (ObjectT::*x)($for j , [[P$j]])
-
-template <class ObjectT, class R$for j [[,
-          class P$j]]>
-MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>
-Bind(FP_T(method), const scoped_refptr<ObjectT>& object$for j [[,
-     typename detail::identity<P$j>::type p$j]]) {
-  return MethodFunctor$i<ObjectT, FP_T(NONAME), R$for j [[, P$j]]>(
-      method, object.get()$for j [[, p$j]]);
-}
-
-#undef FP_T
-#define FP_T(x) R (*x)($for j , [[P$j]])
-
-template <class R$for j [[,
-          class P$j]]>
-Functor$i<FP_T(NONAME), R$for j [[, P$j]]>
-Bind(FP_T(function)$for j [[,
-     typename detail::identity<P$j>::type p$j]]) {
-  return Functor$i<FP_T(NONAME), R$for j [[, P$j]]>(
-      function$for j [[, p$j]]);
-}
-
-#undef FP_T
-
-]]
-
-}  // namespace rtc
-
-#undef NONAME
-
-#endif  // WEBRTC_BASE_BIND_H_
diff --git a/base/bind_unittest.cc b/base/bind_unittest.cc
index be8d79c..3331591 100644
--- a/base/bind_unittest.cc
+++ b/base/bind_unittest.cc
@@ -8,6 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <type_traits>
+
 #include "webrtc/base/bind.h"
 #include "webrtc/base/gunit.h"
 
@@ -71,26 +73,6 @@
 
 // Try to catch any problem with scoped_refptr type deduction in rtc::Bind at
 // compile time.
-static_assert(
-    is_same<
-        rtc::remove_reference<const scoped_refptr<RefCountInterface>&>::type,
-        const scoped_refptr<RefCountInterface>>::value,
-    "const scoped_refptr& should be captured by value");
-
-static_assert(is_same<rtc::remove_reference<const scoped_refptr<F>&>::type,
-                      const scoped_refptr<F>>::value,
-              "const scoped_refptr& should be captured by value");
-
-static_assert(
-    is_same<rtc::remove_reference<const int&>::type, const int>::value,
-    "const int& should be captured as const int");
-
-static_assert(is_same<rtc::remove_reference<const F&>::type, const F>::value,
-              "const F& should be captured as const F");
-
-static_assert(is_same<rtc::remove_reference<F&>::type, F>::value,
-              "F& should be captured as F");
-
 #define EXPECT_IS_CAPTURED_AS_PTR(T)                              \
   static_assert(is_same<detail::PointerType<T>::type, T*>::value, \
                 "PointerType")
diff --git a/base/template_util.h b/base/template_util.h
index 31464cf..f3565a4 100644
--- a/base/template_util.h
+++ b/base/template_util.h
@@ -48,17 +48,17 @@
 template <class T> struct is_void : false_type {};
 template <> struct is_void<void> : true_type {};
 
-template <class T>
-struct remove_reference {
-  typedef T type;
-};
-template <class T>
-struct remove_reference<T&> {
-  typedef T type;
-};
-template <class T>
-struct remove_reference<T&&> {
-  typedef T type;
+// Helper useful for converting a tuple to variadic template function
+// arguments.
+//
+// sequence_generator<3>::type will be sequence<0, 1, 2>.
+template <int...>
+struct sequence {};
+template <int N, int... S>
+struct sequence_generator : sequence_generator<N - 1, N - 1, S...> {};
+template <int... S>
+struct sequence_generator<0, S...> {
+  typedef sequence<S...> type;
 };
 
 namespace internal {
diff --git a/pc/ortcfactory.cc b/pc/ortcfactory.cc
index 47d39b7..aa5e181 100644
--- a/pc/ortcfactory.cc
+++ b/pc/ortcfactory.cc
@@ -28,10 +28,16 @@
     rtc::PacketSocketFactory* socket_factory) {
   // Hop to signaling thread if needed.
   if (signaling_thread && !signaling_thread->IsCurrent()) {
+    // The template parameters are necessary because there are two
+    // OrtcFactoryInterface::Create methods, so the types can't be derived from
+    // just the function pointer.
     return signaling_thread->Invoke<std::unique_ptr<OrtcFactoryInterface>>(
         RTC_FROM_HERE,
-        rtc::Bind(&OrtcFactoryInterface::Create, network_thread,
-                  signaling_thread, network_manager, socket_factory));
+        rtc::Bind<std::unique_ptr<OrtcFactoryInterface>, rtc::Thread*,
+                  rtc::Thread*, rtc::NetworkManager*,
+                  rtc::PacketSocketFactory*>(&OrtcFactoryInterface::Create,
+                                             network_thread, signaling_thread,
+                                             network_manager, socket_factory));
   }
   OrtcFactory* new_factory =
       new OrtcFactory(network_thread, signaling_thread,