Replace variadic_function.h with variadic templates.

Change-Id: I8e527268405169ea9234b55d9f64f9349164104c
Reviewed-on: https://code-review.googlesource.com/4792
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/BUILD b/BUILD
index 4fd529f..3376943 100644
--- a/BUILD
+++ b/BUILD
@@ -58,7 +58,6 @@
         "re2/re2.h",
         "re2/set.h",
         "re2/stringpiece.h",
-        "re2/variadic_function.h",
     ],
     copts = ["-pthread"],
     linkopts = ["-pthread"],
diff --git a/Makefile b/Makefile
index 411e551..3930d96 100644
--- a/Makefile
+++ b/Makefile
@@ -65,7 +65,6 @@
 	re2/re2.h\
 	re2/set.h\
 	re2/stringpiece.h\
-	re2/variadic_function.h\
 
 HFILES=\
 	util/benchmark.h\
@@ -95,7 +94,6 @@
 	re2/testing/tester.h\
 	re2/unicode_casefold.h\
 	re2/unicode_groups.h\
-	re2/variadic_function.h\
 	re2/walker-inl.h\
 
 OFILES=\
diff --git a/re2/re2.cc b/re2/re2.cc
index 492ffaf..6bc5edd 100644
--- a/re2/re2.cc
+++ b/re2/re2.cc
@@ -26,11 +26,6 @@
 static const int kMaxArgs = 16;
 static const int kVecSize = 1+kMaxArgs;
 
-const VariadicFunction2<bool, const StringPiece&, const RE2&, RE2::Arg, RE2::FullMatchN> RE2::FullMatch = {};
-const VariadicFunction2<bool, const StringPiece&, const RE2&, RE2::Arg, RE2::PartialMatchN> RE2::PartialMatch = {};
-const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::ConsumeN> RE2::Consume = {};
-const VariadicFunction2<bool, StringPiece*, const RE2&, RE2::Arg, RE2::FindAndConsumeN> RE2::FindAndConsume = {};
-
 // This will trigger LNK2005 error in MSVC.
 #ifndef _MSC_VER
 const int RE2::Options::kDefaultMaxMem;  // initialized in re2.h
diff --git a/re2/re2.h b/re2/re2.h
index 4a8c5c8..82a4003 100644
--- a/re2/re2.h
+++ b/re2/re2.h
@@ -184,7 +184,6 @@
 #include <mutex>
 #include <string>
 #include "re2/stringpiece.h"
-#include "re2/variadic_function.h"
 
 #ifndef RE2_HAVE_LONGLONG
 #define RE2_HAVE_LONGLONG 1
@@ -290,11 +289,11 @@
 
   /***** The useful part: the matching interface *****/
 
-  // Matches "text" against "pattern".  If pointer arguments are
+  // Matches "text" against "re".  If pointer arguments are
   // supplied, copies matched sub-patterns into them.
   //
   // You can pass in a "const char*" or a "string" for "text".
-  // You can pass in a "const char*" or a "string" or a "RE2" for "pattern".
+  // You can pass in a "const char*" or a "string" or a "RE2" for "re".
   //
   // The provided pointer arguments can be pointers to any scalar numeric
   // type, or one of:
@@ -304,7 +303,7 @@
   //    (void*)NULL     (the corresponding matched sub-pattern is not copied)
   //
   // Returns true iff all of the following conditions are satisfied:
-  //   a. "text" matches "pattern" exactly
+  //   a. "text" matches "re" exactly
   //   b. The number of matched sub-patterns is >= number of supplied pointers
   //   c. The "i"th argument has a suitable type for holding the
   //      string captured as the "i"th sub-pattern.  If you pass in
@@ -320,32 +319,58 @@
   //    RE2::FullMatch("abc", "[a-z]+(\\d+)?", &number);
   static bool FullMatchN(const StringPiece& text, const RE2& re,
                          const Arg* const args[], int argc);
-  static const VariadicFunction2<
-      bool, const StringPiece&, const RE2&, Arg, RE2::FullMatchN> FullMatch;
 
-  // Exactly like FullMatch(), except that "pattern" is allowed to match
+  // Exactly like FullMatch(), except that "re" is allowed to match
   // a substring of "text".
-  static bool PartialMatchN(const StringPiece& text, const RE2& re, // 3..16 args
+  static bool PartialMatchN(const StringPiece& text, const RE2& re,
                             const Arg* const args[], int argc);
-  static const VariadicFunction2<
-      bool, const StringPiece&, const RE2&, Arg, RE2::PartialMatchN> PartialMatch;
 
-  // Like FullMatch() and PartialMatch(), except that pattern has to
-  // match a prefix of "text", and "input" is advanced past the matched
+  // Like FullMatch() and PartialMatch(), except that "re" has to match
+  // a prefix of the text, and "input" is advanced past the matched
   // text.  Note: "input" is modified iff this routine returns true.
-  static bool ConsumeN(StringPiece* input, const RE2& pattern, // 3..16 args
+  static bool ConsumeN(StringPiece* input, const RE2& re,
                        const Arg* const args[], int argc);
-  static const VariadicFunction2<
-      bool, StringPiece*, const RE2&, Arg, RE2::ConsumeN> Consume;
 
-  // Like Consume(..), but does not anchor the match at the beginning of the
-  // string.  That is, "pattern" need not start its match at the beginning of
-  // "input".  For example, "FindAndConsume(s, "(\\w+)", &word)" finds the next
-  // word in "s" and stores it in "word".
-  static bool FindAndConsumeN(StringPiece* input, const RE2& pattern,
-                             const Arg* const args[], int argc);
-  static const VariadicFunction2<
-      bool, StringPiece*, const RE2&, Arg, RE2::FindAndConsumeN> FindAndConsume;
+  // Like Consume(), but does not anchor the match at the beginning of
+  // the text.  That is, "re" need not start its match at the beginning
+  // of "input".  For example, "FindAndConsume(s, "(\\w+)", &word)" finds
+  // the next word in "s" and stores it in "word".
+  static bool FindAndConsumeN(StringPiece* input, const RE2& re,
+                              const Arg* const args[], int argc);
+
+ private:
+  template <typename F, typename SP, typename... A>
+  static inline bool Apply(F f, SP sp, const RE2& re, const A&... a) {
+    const Arg* const args[] = {&a...};
+    constexpr int argc = sizeof...(a);
+    return f(sp, re, args, argc);
+  }
+
+ public:
+  // In order to allow FullMatch() et al. to be called with a varying number
+  // of arguments of varying types, we use two layers of variadic templates.
+  // The first layer constructs the temporary Arg objects. The second layer
+  // (above) constructs the array of pointers to the temporary Arg objects.
+
+  template <typename... A>
+  static bool FullMatch(const StringPiece& text, const RE2& re, A... a) {
+    return Apply(FullMatchN, text, re, Arg(a)...);
+  }
+
+  template <typename... A>
+  static bool PartialMatch(const StringPiece& text, const RE2& re, A... a) {
+    return Apply(PartialMatchN, text, re, Arg(a)...);
+  }
+
+  template <typename... A>
+  static bool Consume(StringPiece* input, const RE2& re, A... a) {
+    return Apply(ConsumeN, input, re, Arg(a)...);
+  }
+
+  template <typename... A>
+  static bool FindAndConsume(StringPiece* input, const RE2& re, A... a) {
+    return Apply(FindAndConsumeN, input, re, Arg(a)...);
+  }
 
   // Replace the first match of "pattern" in "str" with "rewrite".
   // Within "rewrite", backslash-escaped digits (\1 to \9) can be
diff --git a/re2/variadic_function.h b/re2/variadic_function.h
deleted file mode 100644
index 7c7d6d5..0000000
--- a/re2/variadic_function.h
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2010 The RE2 Authors.  All Rights Reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#ifndef RE2_VARIADIC_FUNCTION_H_
-#define RE2_VARIADIC_FUNCTION_H_
-
-namespace re2 {
-
-template <typename Result, typename Param0, typename Param1, typename Arg,
-          Result (*Func)(Param0, Param1, const Arg* const [], int count)>
-class VariadicFunction2 {
- public:
-  Result operator()(Param0 p0, Param1 p1) const {
-    return Func(p0, p1, 0, 0);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0) const {
-    const Arg* const args[] = { &a0 };
-    return Func(p0, p1, args, 1);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1) const {
-    const Arg* const args[] = { &a0, &a1 };
-    return Func(p0, p1, args, 2);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2) const {
-    const Arg* const args[] = { &a0, &a1, &a2 };
-    return Func(p0, p1, args, 3);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3 };
-    return Func(p0, p1, args, 4);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4 };
-    return Func(p0, p1, args, 5);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5 };
-    return Func(p0, p1, args, 6);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6 };
-    return Func(p0, p1, args, 7);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7 };
-    return Func(p0, p1, args, 8);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8 };
-    return Func(p0, p1, args, 9);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9 };
-    return Func(p0, p1, args, 10);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10 };
-    return Func(p0, p1, args, 11);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11 };
-    return Func(p0, p1, args, 12);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12 };
-    return Func(p0, p1, args, 13);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13 };
-    return Func(p0, p1, args, 14);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14 };
-    return Func(p0, p1, args, 15);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15 };
-    return Func(p0, p1, args, 16);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16 };
-    return Func(p0, p1, args, 17);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17 };
-    return Func(p0, p1, args, 18);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18 };
-    return Func(p0, p1, args, 19);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19 };
-    return Func(p0, p1, args, 20);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19,
-        &a20 };
-    return Func(p0, p1, args, 21);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21 };
-    return Func(p0, p1, args, 22);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22 };
-    return Func(p0, p1, args, 23);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23 };
-    return Func(p0, p1, args, 24);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24 };
-    return Func(p0, p1, args, 25);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24, const Arg& a25) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24, &a25 };
-    return Func(p0, p1, args, 26);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24, const Arg& a25,
-      const Arg& a26) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24, &a25, &a26 };
-    return Func(p0, p1, args, 27);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24, const Arg& a25,
-      const Arg& a26, const Arg& a27) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24, &a25, &a26, &a27 };
-    return Func(p0, p1, args, 28);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24, const Arg& a25,
-      const Arg& a26, const Arg& a27, const Arg& a28) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28 };
-    return Func(p0, p1, args, 29);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24, const Arg& a25,
-      const Arg& a26, const Arg& a27, const Arg& a28, const Arg& a29) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29 };
-    return Func(p0, p1, args, 30);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24, const Arg& a25,
-      const Arg& a26, const Arg& a27, const Arg& a28, const Arg& a29,
-      const Arg& a30) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30 };
-    return Func(p0, p1, args, 31);
-  }
-
-  Result operator()(Param0 p0, Param1 p1, const Arg& a0, const Arg& a1,
-      const Arg& a2, const Arg& a3, const Arg& a4, const Arg& a5,
-      const Arg& a6, const Arg& a7, const Arg& a8, const Arg& a9,
-      const Arg& a10, const Arg& a11, const Arg& a12, const Arg& a13,
-      const Arg& a14, const Arg& a15, const Arg& a16, const Arg& a17,
-      const Arg& a18, const Arg& a19, const Arg& a20, const Arg& a21,
-      const Arg& a22, const Arg& a23, const Arg& a24, const Arg& a25,
-      const Arg& a26, const Arg& a27, const Arg& a28, const Arg& a29,
-      const Arg& a30, const Arg& a31) const {
-    const Arg* const args[] = { &a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8,
-        &a9, &a10, &a11, &a12, &a13, &a14, &a15, &a16, &a17, &a18, &a19, &a20,
-        &a21, &a22, &a23, &a24, &a25, &a26, &a27, &a28, &a29, &a30, &a31 };
-    return Func(p0, p1, args, 32);
-  }
-};
-
-}  // namespace re2
-
-#endif  // RE2_VARIADIC_FUNCTION_H_