Migrate to the new benchmark API.

Change-Id: I3b206890ac24a449bb8af2dd366a22e92521fed2
Reviewed-on: https://code-review.googlesource.com/c/re2/+/46692
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/re2/testing/regexp_benchmark.cc b/re2/testing/regexp_benchmark.cc
index 968fb86..9af9b34 100644
--- a/re2/testing/regexp_benchmark.cc
+++ b/re2/testing/regexp_benchmark.cc
@@ -109,29 +109,24 @@
 // Defined at bottom of file, but they are repetitive
 // and not interesting.
 
-typedef void SearchImpl(int iters, const char* regexp, const StringPiece& text,
-             Prog::Anchor anchor, bool expect_match);
+typedef void SearchImpl(benchmark::State& state, const char* regexp,
+                        const StringPiece& text, Prog::Anchor anchor,
+                        bool expect_match);
 
-SearchImpl SearchDFA, SearchNFA, SearchOnePass, SearchBitState,
-           SearchPCRE, SearchRE2,
-           SearchCachedDFA, SearchCachedNFA, SearchCachedOnePass, SearchCachedBitState,
-           SearchCachedPCRE, SearchCachedRE2;
+SearchImpl SearchDFA, SearchNFA, SearchOnePass, SearchBitState, SearchPCRE,
+    SearchRE2, SearchCachedDFA, SearchCachedNFA, SearchCachedOnePass,
+    SearchCachedBitState, SearchCachedPCRE, SearchCachedRE2;
 
-typedef void ParseImpl(int iters, const char* regexp, const StringPiece& text);
+typedef void ParseImpl(benchmark::State& state, const char* regexp,
+                       const StringPiece& text);
 
-ParseImpl Parse1NFA, Parse1OnePass, Parse1BitState,
-          Parse1PCRE, Parse1RE2,
-          Parse1Backtrack,
-          Parse1CachedNFA, Parse1CachedOnePass, Parse1CachedBitState,
-          Parse1CachedPCRE, Parse1CachedRE2,
-          Parse1CachedBacktrack;
+ParseImpl Parse1NFA, Parse1OnePass, Parse1BitState, Parse1PCRE, Parse1RE2,
+    Parse1Backtrack, Parse1CachedNFA, Parse1CachedOnePass, Parse1CachedBitState,
+    Parse1CachedPCRE, Parse1CachedRE2, Parse1CachedBacktrack;
 
-ParseImpl Parse3NFA, Parse3OnePass, Parse3BitState,
-          Parse3PCRE, Parse3RE2,
-          Parse3Backtrack,
-          Parse3CachedNFA, Parse3CachedOnePass, Parse3CachedBitState,
-          Parse3CachedPCRE, Parse3CachedRE2,
-          Parse3CachedBacktrack;
+ParseImpl Parse3NFA, Parse3OnePass, Parse3BitState, Parse3PCRE, Parse3RE2,
+    Parse3Backtrack, Parse3CachedNFA, Parse3CachedOnePass, Parse3CachedBitState,
+    Parse3CachedPCRE, Parse3CachedRE2, Parse3CachedBacktrack;
 
 ParseImpl SearchParse2CachedPCRE, SearchParse2CachedRE2;
 
@@ -156,14 +151,11 @@
 
 // Makes text of size nbytes, then calls run to search
 // the text for regexp iters times.
-void Search(int iters, int nbytes, const char* regexp, SearchImpl* search) {
-  StopBenchmarkTiming();
+void Search(benchmark::State& state, const char* regexp, SearchImpl* search) {
   std::string s;
-  MakeText(&s, nbytes);
-  BenchmarkMemoryUsage();
-  StartBenchmarkTiming();
-  search(iters, regexp, s, Prog::kUnanchored, false);
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iters)*nbytes);
+  MakeText(&s, state.range());
+  search(state, regexp, s, Prog::kUnanchored, false);
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
 // These two are easy because they start with an A,
@@ -189,10 +181,10 @@
 #define PARENS     "([ -~])*(A)(B)(C)(D)(E)(F)(G)(H)(I)(J)(K)(L)(M)" \
                    "(N)(O)(P)(Q)(R)(S)(T)(U)(V)(W)(X)(Y)(Z)$"
 
-void Search_Easy0_CachedDFA(int i, int n)     { Search(i, n, EASY0, SearchCachedDFA); }
-void Search_Easy0_CachedNFA(int i, int n)     { Search(i, n, EASY0, SearchCachedNFA); }
-void Search_Easy0_CachedPCRE(int i, int n)    { Search(i, n, EASY0, SearchCachedPCRE); }
-void Search_Easy0_CachedRE2(int i, int n)     { Search(i, n, EASY0, SearchCachedRE2); }
+void Search_Easy0_CachedDFA(benchmark::State& state)     { Search(state, EASY0, SearchCachedDFA); }
+void Search_Easy0_CachedNFA(benchmark::State& state)     { Search(state, EASY0, SearchCachedNFA); }
+void Search_Easy0_CachedPCRE(benchmark::State& state)    { Search(state, EASY0, SearchCachedPCRE); }
+void Search_Easy0_CachedRE2(benchmark::State& state)     { Search(state, EASY0, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_Easy0_CachedDFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Easy0_CachedNFA,     8, 256<<10)->ThreadRange(1, NumCPUs());
@@ -201,10 +193,10 @@
 #endif
 BENCHMARK_RANGE(Search_Easy0_CachedRE2,     8, 16<<20)->ThreadRange(1, NumCPUs());
 
-void Search_Easy1_CachedDFA(int i, int n)     { Search(i, n, EASY1, SearchCachedDFA); }
-void Search_Easy1_CachedNFA(int i, int n)     { Search(i, n, EASY1, SearchCachedNFA); }
-void Search_Easy1_CachedPCRE(int i, int n)    { Search(i, n, EASY1, SearchCachedPCRE); }
-void Search_Easy1_CachedRE2(int i, int n)     { Search(i, n, EASY1, SearchCachedRE2); }
+void Search_Easy1_CachedDFA(benchmark::State& state)     { Search(state, EASY1, SearchCachedDFA); }
+void Search_Easy1_CachedNFA(benchmark::State& state)     { Search(state, EASY1, SearchCachedNFA); }
+void Search_Easy1_CachedPCRE(benchmark::State& state)    { Search(state, EASY1, SearchCachedPCRE); }
+void Search_Easy1_CachedRE2(benchmark::State& state)     { Search(state, EASY1, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_Easy1_CachedDFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Easy1_CachedNFA,     8, 256<<10)->ThreadRange(1, NumCPUs());
@@ -213,10 +205,10 @@
 #endif
 BENCHMARK_RANGE(Search_Easy1_CachedRE2,     8, 16<<20)->ThreadRange(1, NumCPUs());
 
-void Search_Medium_CachedDFA(int i, int n)     { Search(i, n, MEDIUM, SearchCachedDFA); }
-void Search_Medium_CachedNFA(int i, int n)     { Search(i, n, MEDIUM, SearchCachedNFA); }
-void Search_Medium_CachedPCRE(int i, int n)    { Search(i, n, MEDIUM, SearchCachedPCRE); }
-void Search_Medium_CachedRE2(int i, int n)     { Search(i, n, MEDIUM, SearchCachedRE2); }
+void Search_Medium_CachedDFA(benchmark::State& state)     { Search(state, MEDIUM, SearchCachedDFA); }
+void Search_Medium_CachedNFA(benchmark::State& state)     { Search(state, MEDIUM, SearchCachedNFA); }
+void Search_Medium_CachedPCRE(benchmark::State& state)    { Search(state, MEDIUM, SearchCachedPCRE); }
+void Search_Medium_CachedRE2(benchmark::State& state)     { Search(state, MEDIUM, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_Medium_CachedDFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Medium_CachedNFA,     8, 256<<10)->ThreadRange(1, NumCPUs());
@@ -225,10 +217,10 @@
 #endif
 BENCHMARK_RANGE(Search_Medium_CachedRE2,     8, 16<<20)->ThreadRange(1, NumCPUs());
 
-void Search_Hard_CachedDFA(int i, int n)     { Search(i, n, HARD, SearchCachedDFA); }
-void Search_Hard_CachedNFA(int i, int n)     { Search(i, n, HARD, SearchCachedNFA); }
-void Search_Hard_CachedPCRE(int i, int n)    { Search(i, n, HARD, SearchCachedPCRE); }
-void Search_Hard_CachedRE2(int i, int n)     { Search(i, n, HARD, SearchCachedRE2); }
+void Search_Hard_CachedDFA(benchmark::State& state)     { Search(state, HARD, SearchCachedDFA); }
+void Search_Hard_CachedNFA(benchmark::State& state)     { Search(state, HARD, SearchCachedNFA); }
+void Search_Hard_CachedPCRE(benchmark::State& state)    { Search(state, HARD, SearchCachedPCRE); }
+void Search_Hard_CachedRE2(benchmark::State& state)     { Search(state, HARD, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_Hard_CachedDFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Hard_CachedNFA,     8, 256<<10)->ThreadRange(1, NumCPUs());
@@ -237,10 +229,10 @@
 #endif
 BENCHMARK_RANGE(Search_Hard_CachedRE2,     8, 16<<20)->ThreadRange(1, NumCPUs());
 
-void Search_Fanout_CachedDFA(int i, int n)     { Search(i, n, FANOUT, SearchCachedDFA); }
-void Search_Fanout_CachedNFA(int i, int n)     { Search(i, n, FANOUT, SearchCachedNFA); }
-void Search_Fanout_CachedPCRE(int i, int n)    { Search(i, n, FANOUT, SearchCachedPCRE); }
-void Search_Fanout_CachedRE2(int i, int n)     { Search(i, n, FANOUT, SearchCachedRE2); }
+void Search_Fanout_CachedDFA(benchmark::State& state)     { Search(state, FANOUT, SearchCachedDFA); }
+void Search_Fanout_CachedNFA(benchmark::State& state)     { Search(state, FANOUT, SearchCachedNFA); }
+void Search_Fanout_CachedPCRE(benchmark::State& state)    { Search(state, FANOUT, SearchCachedPCRE); }
+void Search_Fanout_CachedRE2(benchmark::State& state)     { Search(state, FANOUT, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_Fanout_CachedDFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Fanout_CachedNFA,     8, 256<<10)->ThreadRange(1, NumCPUs());
@@ -249,10 +241,10 @@
 #endif
 BENCHMARK_RANGE(Search_Fanout_CachedRE2,     8, 16<<20)->ThreadRange(1, NumCPUs());
 
-void Search_Parens_CachedDFA(int i, int n)     { Search(i, n, PARENS, SearchCachedDFA); }
-void Search_Parens_CachedNFA(int i, int n)     { Search(i, n, PARENS, SearchCachedNFA); }
-void Search_Parens_CachedPCRE(int i, int n)    { Search(i, n, PARENS, SearchCachedPCRE); }
-void Search_Parens_CachedRE2(int i, int n)     { Search(i, n, PARENS, SearchCachedRE2); }
+void Search_Parens_CachedDFA(benchmark::State& state)     { Search(state, PARENS, SearchCachedDFA); }
+void Search_Parens_CachedNFA(benchmark::State& state)     { Search(state, PARENS, SearchCachedNFA); }
+void Search_Parens_CachedPCRE(benchmark::State& state)    { Search(state, PARENS, SearchCachedPCRE); }
+void Search_Parens_CachedRE2(benchmark::State& state)     { Search(state, PARENS, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_Parens_CachedDFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Parens_CachedNFA,     8, 256<<10)->ThreadRange(1, NumCPUs());
@@ -261,24 +253,21 @@
 #endif
 BENCHMARK_RANGE(Search_Parens_CachedRE2,     8, 16<<20)->ThreadRange(1, NumCPUs());
 
-void SearchBigFixed(int iters, int nbytes, SearchImpl* search) {
-  StopBenchmarkTiming();
+void SearchBigFixed(benchmark::State& state, SearchImpl* search) {
   std::string s;
-  s.append(nbytes/2, 'x');
+  s.append(state.range()/2, 'x');
   std::string regexp = "^" + s + ".*$";
   std::string t;
-  MakeText(&t, nbytes/2);
+  MakeText(&t, state.range()/2);
   s += t;
-  BenchmarkMemoryUsage();
-  StartBenchmarkTiming();
-  search(iters, regexp.c_str(), s, Prog::kUnanchored, true);
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iters)*nbytes);
+  search(state, regexp.c_str(), s, Prog::kUnanchored, true);
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
-void Search_BigFixed_CachedDFA(int i, int n)     { SearchBigFixed(i, n, SearchCachedDFA); }
-void Search_BigFixed_CachedNFA(int i, int n)     { SearchBigFixed(i, n, SearchCachedNFA); }
-void Search_BigFixed_CachedPCRE(int i, int n)    { SearchBigFixed(i, n, SearchCachedPCRE); }
-void Search_BigFixed_CachedRE2(int i, int n)     { SearchBigFixed(i, n, SearchCachedRE2); }
+void Search_BigFixed_CachedDFA(benchmark::State& state)     { SearchBigFixed(state, SearchCachedDFA); }
+void Search_BigFixed_CachedNFA(benchmark::State& state)     { SearchBigFixed(state, SearchCachedNFA); }
+void Search_BigFixed_CachedPCRE(benchmark::State& state)    { SearchBigFixed(state, SearchCachedPCRE); }
+void Search_BigFixed_CachedRE2(benchmark::State& state)     { SearchBigFixed(state, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_BigFixed_CachedDFA,     8, 1<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_BigFixed_CachedNFA,     8, 32<<10)->ThreadRange(1, NumCPUs());
@@ -289,43 +278,39 @@
 
 // Benchmark: FindAndConsume
 
-void FindAndConsume(int iters, int nbytes) {
-  StopBenchmarkTiming();
+void FindAndConsume(benchmark::State& state) {
   std::string s;
-  MakeText(&s, nbytes);
+  MakeText(&s, state.range());
   s.append("Hello World");
-  StartBenchmarkTiming();
   RE2 re("((Hello World))");
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     StringPiece t = s;
     StringPiece u;
     CHECK(RE2::FindAndConsume(&t, re, &u));
     CHECK_EQ(u, "Hello World");
   }
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iters)*nbytes);
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
 BENCHMARK_RANGE(FindAndConsume, 8, 16<<20)->ThreadRange(1, NumCPUs());
 
 // Benchmark: successful anchored search.
 
-void SearchSuccess(int iters, int nbytes, const char* regexp, SearchImpl* search) {
-  StopBenchmarkTiming();
+void SearchSuccess(benchmark::State& state, const char* regexp,
+                   SearchImpl* search) {
   std::string s;
-  MakeText(&s, nbytes);
-  BenchmarkMemoryUsage();
-  StartBenchmarkTiming();
-  search(iters, regexp, s, Prog::kAnchored, true);
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iters)*nbytes);
+  MakeText(&s, state.range());
+  search(state, regexp, s, Prog::kAnchored, true);
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
 // Unambiguous search (RE2 can use OnePass).
 
-void Search_Success_DFA(int i, int n)     { SearchSuccess(i, n, ".*$", SearchDFA); }
-void Search_Success_NFA(int i, int n)     { SearchSuccess(i, n, ".*$", SearchNFA); }
-void Search_Success_PCRE(int i, int n)    { SearchSuccess(i, n, ".*$", SearchPCRE); }
-void Search_Success_RE2(int i, int n)     { SearchSuccess(i, n, ".*$", SearchRE2); }
-void Search_Success_OnePass(int i, int n) { SearchSuccess(i, n, ".*$", SearchOnePass); }
+void Search_Success_DFA(benchmark::State& state)     { SearchSuccess(state, ".*$", SearchDFA); }
+void Search_Success_NFA(benchmark::State& state)     { SearchSuccess(state, ".*$", SearchNFA); }
+void Search_Success_PCRE(benchmark::State& state)    { SearchSuccess(state, ".*$", SearchPCRE); }
+void Search_Success_RE2(benchmark::State& state)     { SearchSuccess(state, ".*$", SearchRE2); }
+void Search_Success_OnePass(benchmark::State& state) { SearchSuccess(state, ".*$", SearchOnePass); }
 
 BENCHMARK_RANGE(Search_Success_DFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Success_NFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
@@ -335,11 +320,11 @@
 BENCHMARK_RANGE(Search_Success_RE2,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Success_OnePass, 8, 2<<20)->ThreadRange(1, NumCPUs());
 
-void Search_Success_CachedDFA(int i, int n)     { SearchSuccess(i, n, ".*$", SearchCachedDFA); }
-void Search_Success_CachedNFA(int i, int n)     { SearchSuccess(i, n, ".*$", SearchCachedNFA); }
-void Search_Success_CachedPCRE(int i, int n)    { SearchSuccess(i, n, ".*$", SearchCachedPCRE); }
-void Search_Success_CachedRE2(int i, int n)     { SearchSuccess(i, n, ".*$", SearchCachedRE2); }
-void Search_Success_CachedOnePass(int i, int n) { SearchSuccess(i, n, ".*$", SearchCachedOnePass); }
+void Search_Success_CachedDFA(benchmark::State& state)     { SearchSuccess(state, ".*$", SearchCachedDFA); }
+void Search_Success_CachedNFA(benchmark::State& state)     { SearchSuccess(state, ".*$", SearchCachedNFA); }
+void Search_Success_CachedPCRE(benchmark::State& state)    { SearchSuccess(state, ".*$", SearchCachedPCRE); }
+void Search_Success_CachedRE2(benchmark::State& state)     { SearchSuccess(state, ".*$", SearchCachedRE2); }
+void Search_Success_CachedOnePass(benchmark::State& state) { SearchSuccess(state, ".*$", SearchCachedOnePass); }
 
 BENCHMARK_RANGE(Search_Success_CachedDFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Success_CachedNFA,     8, 16<<20)->ThreadRange(1, NumCPUs());
@@ -352,11 +337,11 @@
 // Ambiguous search (RE2 cannot use OnePass).
 // Used to be ".*.$", but that is coalesced to ".+$" these days.
 
-void Search_Success1_DFA(int i, int n)      { SearchSuccess(i, n, ".*\\C$", SearchDFA); }
-void Search_Success1_NFA(int i, int n)      { SearchSuccess(i, n, ".*\\C$", SearchNFA); }
-void Search_Success1_PCRE(int i, int n)     { SearchSuccess(i, n, ".*\\C$", SearchPCRE); }
-void Search_Success1_RE2(int i, int n)      { SearchSuccess(i, n, ".*\\C$", SearchRE2); }
-void Search_Success1_BitState(int i, int n) { SearchSuccess(i, n, ".*\\C$", SearchBitState); }
+void Search_Success1_DFA(benchmark::State& state)      { SearchSuccess(state, ".*\\C$", SearchDFA); }
+void Search_Success1_NFA(benchmark::State& state)      { SearchSuccess(state, ".*\\C$", SearchNFA); }
+void Search_Success1_PCRE(benchmark::State& state)     { SearchSuccess(state, ".*\\C$", SearchPCRE); }
+void Search_Success1_RE2(benchmark::State& state)      { SearchSuccess(state, ".*\\C$", SearchRE2); }
+void Search_Success1_BitState(benchmark::State& state) { SearchSuccess(state, ".*\\C$", SearchBitState); }
 
 BENCHMARK_RANGE(Search_Success1_DFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Success1_NFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
@@ -366,11 +351,11 @@
 BENCHMARK_RANGE(Search_Success1_RE2,      8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Success1_BitState, 8, 2<<20)->ThreadRange(1, NumCPUs());
 
-void Search_Success1_CachedDFA(int i, int n)      { SearchSuccess(i, n, ".*\\C$", SearchCachedDFA); }
-void Search_Success1_CachedNFA(int i, int n)      { SearchSuccess(i, n, ".*\\C$", SearchCachedNFA); }
-void Search_Success1_CachedPCRE(int i, int n)     { SearchSuccess(i, n, ".*\\C$", SearchCachedPCRE); }
-void Search_Success1_CachedRE2(int i, int n)      { SearchSuccess(i, n, ".*\\C$", SearchCachedRE2); }
-void Search_Success1_CachedBitState(int i, int n) { SearchSuccess(i, n, ".*\\C$", SearchCachedBitState); }
+void Search_Success1_CachedDFA(benchmark::State& state)      { SearchSuccess(state, ".*\\C$", SearchCachedDFA); }
+void Search_Success1_CachedNFA(benchmark::State& state)      { SearchSuccess(state, ".*\\C$", SearchCachedNFA); }
+void Search_Success1_CachedPCRE(benchmark::State& state)     { SearchSuccess(state, ".*\\C$", SearchCachedPCRE); }
+void Search_Success1_CachedRE2(benchmark::State& state)      { SearchSuccess(state, ".*\\C$", SearchCachedRE2); }
+void Search_Success1_CachedBitState(benchmark::State& state) { SearchSuccess(state, ".*\\C$", SearchCachedBitState); }
 
 BENCHMARK_RANGE(Search_Success1_CachedDFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_Success1_CachedNFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
@@ -383,22 +368,19 @@
 // Benchmark: AltMatch optimisation (just to verify that it works)
 // Note that OnePass doesn't implement it!
 
-void SearchAltMatch(int iters, int nbytes, SearchImpl* search) {
-  StopBenchmarkTiming();
+void SearchAltMatch(benchmark::State& state, SearchImpl* search) {
   std::string s;
-  MakeText(&s, nbytes);
-  BenchmarkMemoryUsage();
-  StartBenchmarkTiming();
-  search(iters, "\\C*", s, Prog::kAnchored, true);
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iters)*nbytes);
+  MakeText(&s, state.range());
+  search(state, "\\C*", s, Prog::kAnchored, true);
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
-void Search_AltMatch_DFA(int i, int n)      { SearchAltMatch(i, n, SearchDFA); }
-void Search_AltMatch_NFA(int i, int n)      { SearchAltMatch(i, n, SearchNFA); }
-void Search_AltMatch_OnePass(int i, int n)  { SearchAltMatch(i, n, SearchOnePass); }
-void Search_AltMatch_BitState(int i, int n) { SearchAltMatch(i, n, SearchBitState); }
-void Search_AltMatch_PCRE(int i, int n)     { SearchAltMatch(i, n, SearchPCRE); }
-void Search_AltMatch_RE2(int i, int n)      { SearchAltMatch(i, n, SearchRE2); }
+void Search_AltMatch_DFA(benchmark::State& state)      { SearchAltMatch(state, SearchDFA); }
+void Search_AltMatch_NFA(benchmark::State& state)      { SearchAltMatch(state, SearchNFA); }
+void Search_AltMatch_OnePass(benchmark::State& state)  { SearchAltMatch(state, SearchOnePass); }
+void Search_AltMatch_BitState(benchmark::State& state) { SearchAltMatch(state, SearchBitState); }
+void Search_AltMatch_PCRE(benchmark::State& state)     { SearchAltMatch(state, SearchPCRE); }
+void Search_AltMatch_RE2(benchmark::State& state)      { SearchAltMatch(state, SearchRE2); }
 
 BENCHMARK_RANGE(Search_AltMatch_DFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_AltMatch_NFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
@@ -409,12 +391,12 @@
 #endif
 BENCHMARK_RANGE(Search_AltMatch_RE2,      8, 16<<20)->ThreadRange(1, NumCPUs());
 
-void Search_AltMatch_CachedDFA(int i, int n)      { SearchAltMatch(i, n, SearchCachedDFA); }
-void Search_AltMatch_CachedNFA(int i, int n)      { SearchAltMatch(i, n, SearchCachedNFA); }
-void Search_AltMatch_CachedOnePass(int i, int n)  { SearchAltMatch(i, n, SearchCachedOnePass); }
-void Search_AltMatch_CachedBitState(int i, int n) { SearchAltMatch(i, n, SearchCachedBitState); }
-void Search_AltMatch_CachedPCRE(int i, int n)     { SearchAltMatch(i, n, SearchCachedPCRE); }
-void Search_AltMatch_CachedRE2(int i, int n)      { SearchAltMatch(i, n, SearchCachedRE2); }
+void Search_AltMatch_CachedDFA(benchmark::State& state)      { SearchAltMatch(state, SearchCachedDFA); }
+void Search_AltMatch_CachedNFA(benchmark::State& state)      { SearchAltMatch(state, SearchCachedNFA); }
+void Search_AltMatch_CachedOnePass(benchmark::State& state)  { SearchAltMatch(state, SearchCachedOnePass); }
+void Search_AltMatch_CachedBitState(benchmark::State& state) { SearchAltMatch(state, SearchCachedBitState); }
+void Search_AltMatch_CachedPCRE(benchmark::State& state)     { SearchAltMatch(state, SearchCachedPCRE); }
+void Search_AltMatch_CachedRE2(benchmark::State& state)      { SearchAltMatch(state, SearchCachedRE2); }
 
 BENCHMARK_RANGE(Search_AltMatch_CachedDFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
 BENCHMARK_RANGE(Search_AltMatch_CachedNFA,      8, 16<<20)->ThreadRange(1, NumCPUs());
@@ -427,19 +409,18 @@
 
 // Benchmark: use regexp to find phone number.
 
-void SearchDigits(int iters, SearchImpl* search) {
+void SearchDigits(benchmark::State& state, SearchImpl* search) {
   StringPiece s("650-253-0001");
-  BenchmarkMemoryUsage();
-  search(iters, "([0-9]+)-([0-9]+)-([0-9]+)", s, Prog::kAnchored, true);
-  SetBenchmarkItemsProcessed(iters);
+  search(state, "([0-9]+)-([0-9]+)-([0-9]+)", s, Prog::kAnchored, true);
+  state.SetItemsProcessed(state.iterations());
 }
 
-void Search_Digits_DFA(int i)         { SearchDigits(i, SearchDFA); }
-void Search_Digits_NFA(int i)         { SearchDigits(i, SearchNFA); }
-void Search_Digits_OnePass(int i)     { SearchDigits(i, SearchOnePass); }
-void Search_Digits_PCRE(int i)        { SearchDigits(i, SearchPCRE); }
-void Search_Digits_RE2(int i)         { SearchDigits(i, SearchRE2); }
-void Search_Digits_BitState(int i)         { SearchDigits(i, SearchBitState); }
+void Search_Digits_DFA(benchmark::State& state)         { SearchDigits(state, SearchDFA); }
+void Search_Digits_NFA(benchmark::State& state)         { SearchDigits(state, SearchNFA); }
+void Search_Digits_OnePass(benchmark::State& state)     { SearchDigits(state, SearchOnePass); }
+void Search_Digits_PCRE(benchmark::State& state)        { SearchDigits(state, SearchPCRE); }
+void Search_Digits_RE2(benchmark::State& state)         { SearchDigits(state, SearchRE2); }
+void Search_Digits_BitState(benchmark::State& state)    { SearchDigits(state, SearchBitState); }
 
 BENCHMARK(Search_Digits_DFA)->ThreadRange(1, NumCPUs());
 BENCHMARK(Search_Digits_NFA)->ThreadRange(1, NumCPUs());
@@ -452,19 +433,19 @@
 
 // Benchmark: use regexp to parse digit fields in phone number.
 
-void Parse3Digits(int iters,
-               void (*parse3)(int, const char*, const StringPiece&)) {
-  BenchmarkMemoryUsage();
-  parse3(iters, "([0-9]+)-([0-9]+)-([0-9]+)", "650-253-0001");
-  SetBenchmarkItemsProcessed(iters);
+void Parse3Digits(benchmark::State& state,
+                  void (*parse3)(benchmark::State&, const char*,
+                                 const StringPiece&)) {
+  parse3(state, "([0-9]+)-([0-9]+)-([0-9]+)", "650-253-0001");
+  state.SetItemsProcessed(state.iterations());
 }
 
-void Parse_Digits_NFA(int i)         { Parse3Digits(i, Parse3NFA); }
-void Parse_Digits_OnePass(int i)     { Parse3Digits(i, Parse3OnePass); }
-void Parse_Digits_PCRE(int i)        { Parse3Digits(i, Parse3PCRE); }
-void Parse_Digits_RE2(int i)         { Parse3Digits(i, Parse3RE2); }
-void Parse_Digits_Backtrack(int i)   { Parse3Digits(i, Parse3Backtrack); }
-void Parse_Digits_BitState(int i)   { Parse3Digits(i, Parse3BitState); }
+void Parse_Digits_NFA(benchmark::State& state)         { Parse3Digits(state, Parse3NFA); }
+void Parse_Digits_OnePass(benchmark::State& state)     { Parse3Digits(state, Parse3OnePass); }
+void Parse_Digits_PCRE(benchmark::State& state)        { Parse3Digits(state, Parse3PCRE); }
+void Parse_Digits_RE2(benchmark::State& state)         { Parse3Digits(state, Parse3RE2); }
+void Parse_Digits_Backtrack(benchmark::State& state)   { Parse3Digits(state, Parse3Backtrack); }
+void Parse_Digits_BitState(benchmark::State& state)    { Parse3Digits(state, Parse3BitState); }
 
 BENCHMARK(Parse_Digits_NFA)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_Digits_OnePass)->ThreadRange(1, NumCPUs());
@@ -475,12 +456,12 @@
 BENCHMARK(Parse_Digits_Backtrack)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_Digits_BitState)->ThreadRange(1, NumCPUs());
 
-void Parse_CachedDigits_NFA(int i)         { Parse3Digits(i, Parse3CachedNFA); }
-void Parse_CachedDigits_OnePass(int i)     { Parse3Digits(i, Parse3CachedOnePass); }
-void Parse_CachedDigits_PCRE(int i)        { Parse3Digits(i, Parse3CachedPCRE); }
-void Parse_CachedDigits_RE2(int i)         { Parse3Digits(i, Parse3CachedRE2); }
-void Parse_CachedDigits_Backtrack(int i)   { Parse3Digits(i, Parse3CachedBacktrack); }
-void Parse_CachedDigits_BitState(int i)   { Parse3Digits(i, Parse3CachedBitState); }
+void Parse_CachedDigits_NFA(benchmark::State& state)         { Parse3Digits(state, Parse3CachedNFA); }
+void Parse_CachedDigits_OnePass(benchmark::State& state)     { Parse3Digits(state, Parse3CachedOnePass); }
+void Parse_CachedDigits_PCRE(benchmark::State& state)        { Parse3Digits(state, Parse3CachedPCRE); }
+void Parse_CachedDigits_RE2(benchmark::State& state)         { Parse3Digits(state, Parse3CachedRE2); }
+void Parse_CachedDigits_Backtrack(benchmark::State& state)   { Parse3Digits(state, Parse3CachedBacktrack); }
+void Parse_CachedDigits_BitState(benchmark::State& state)    { Parse3Digits(state, Parse3CachedBitState); }
 
 BENCHMARK(Parse_CachedDigits_NFA)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_CachedDigits_OnePass)->ThreadRange(1, NumCPUs());
@@ -491,19 +472,19 @@
 BENCHMARK(Parse_CachedDigits_RE2)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_CachedDigits_BitState)->ThreadRange(1, NumCPUs());
 
-void Parse3DigitDs(int iters,
-               void (*parse3)(int, const char*, const StringPiece&)) {
-  BenchmarkMemoryUsage();
-  parse3(iters, "(\\d+)-(\\d+)-(\\d+)", "650-253-0001");
-  SetBenchmarkItemsProcessed(iters);
+void Parse3DigitDs(benchmark::State& state,
+                   void (*parse3)(benchmark::State&, const char*,
+                                  const StringPiece&)) {
+  parse3(state, "(\\d+)-(\\d+)-(\\d+)", "650-253-0001");
+  state.SetItemsProcessed(state.iterations());
 }
 
-void Parse_DigitDs_NFA(int i)         { Parse3DigitDs(i, Parse3NFA); }
-void Parse_DigitDs_OnePass(int i)     { Parse3DigitDs(i, Parse3OnePass); }
-void Parse_DigitDs_PCRE(int i)        { Parse3DigitDs(i, Parse3PCRE); }
-void Parse_DigitDs_RE2(int i)         { Parse3DigitDs(i, Parse3RE2); }
-void Parse_DigitDs_Backtrack(int i)   { Parse3DigitDs(i, Parse3CachedBacktrack); }
-void Parse_DigitDs_BitState(int i)   { Parse3DigitDs(i, Parse3CachedBitState); }
+void Parse_DigitDs_NFA(benchmark::State& state)         { Parse3DigitDs(state, Parse3NFA); }
+void Parse_DigitDs_OnePass(benchmark::State& state)     { Parse3DigitDs(state, Parse3OnePass); }
+void Parse_DigitDs_PCRE(benchmark::State& state)        { Parse3DigitDs(state, Parse3PCRE); }
+void Parse_DigitDs_RE2(benchmark::State& state)         { Parse3DigitDs(state, Parse3RE2); }
+void Parse_DigitDs_Backtrack(benchmark::State& state)   { Parse3DigitDs(state, Parse3CachedBacktrack); }
+void Parse_DigitDs_BitState(benchmark::State& state)    { Parse3DigitDs(state, Parse3CachedBitState); }
 
 BENCHMARK(Parse_DigitDs_NFA)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_DigitDs_OnePass)->ThreadRange(1, NumCPUs());
@@ -514,12 +495,12 @@
 BENCHMARK(Parse_DigitDs_Backtrack)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_DigitDs_BitState)->ThreadRange(1, NumCPUs());
 
-void Parse_CachedDigitDs_NFA(int i)         { Parse3DigitDs(i, Parse3CachedNFA); }
-void Parse_CachedDigitDs_OnePass(int i)     { Parse3DigitDs(i, Parse3CachedOnePass); }
-void Parse_CachedDigitDs_PCRE(int i)        { Parse3DigitDs(i, Parse3CachedPCRE); }
-void Parse_CachedDigitDs_RE2(int i)         { Parse3DigitDs(i, Parse3CachedRE2); }
-void Parse_CachedDigitDs_Backtrack(int i)   { Parse3DigitDs(i, Parse3CachedBacktrack); }
-void Parse_CachedDigitDs_BitState(int i)   { Parse3DigitDs(i, Parse3CachedBitState); }
+void Parse_CachedDigitDs_NFA(benchmark::State& state)         { Parse3DigitDs(state, Parse3CachedNFA); }
+void Parse_CachedDigitDs_OnePass(benchmark::State& state)     { Parse3DigitDs(state, Parse3CachedOnePass); }
+void Parse_CachedDigitDs_PCRE(benchmark::State& state)        { Parse3DigitDs(state, Parse3CachedPCRE); }
+void Parse_CachedDigitDs_RE2(benchmark::State& state)         { Parse3DigitDs(state, Parse3CachedRE2); }
+void Parse_CachedDigitDs_Backtrack(benchmark::State& state)   { Parse3DigitDs(state, Parse3CachedBacktrack); }
+void Parse_CachedDigitDs_BitState(benchmark::State& state)    { Parse3DigitDs(state, Parse3CachedBitState); }
 
 BENCHMARK(Parse_CachedDigitDs_NFA)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_CachedDigitDs_OnePass)->ThreadRange(1, NumCPUs());
@@ -532,18 +513,18 @@
 
 // Benchmark: splitting off leading number field.
 
-void Parse1Split(int iters,
-              void (*parse1)(int, const char*, const StringPiece&)) {
-  BenchmarkMemoryUsage();
-  parse1(iters, "[0-9]+-(.*)", "650-253-0001");
-  SetBenchmarkItemsProcessed(iters);
+void Parse1Split(benchmark::State& state,
+                 void (*parse1)(benchmark::State&, const char*,
+                                const StringPiece&)) {
+  parse1(state, "[0-9]+-(.*)", "650-253-0001");
+  state.SetItemsProcessed(state.iterations());
 }
 
-void Parse_Split_NFA(int i)         { Parse1Split(i, Parse1NFA); }
-void Parse_Split_OnePass(int i)     { Parse1Split(i, Parse1OnePass); }
-void Parse_Split_PCRE(int i)        { Parse1Split(i, Parse1PCRE); }
-void Parse_Split_RE2(int i)         { Parse1Split(i, Parse1RE2); }
-void Parse_Split_BitState(int i)         { Parse1Split(i, Parse1BitState); }
+void Parse_Split_NFA(benchmark::State& state)         { Parse1Split(state, Parse1NFA); }
+void Parse_Split_OnePass(benchmark::State& state)     { Parse1Split(state, Parse1OnePass); }
+void Parse_Split_PCRE(benchmark::State& state)        { Parse1Split(state, Parse1PCRE); }
+void Parse_Split_RE2(benchmark::State& state)         { Parse1Split(state, Parse1RE2); }
+void Parse_Split_BitState(benchmark::State& state)    { Parse1Split(state, Parse1BitState); }
 
 BENCHMARK(Parse_Split_NFA)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_Split_OnePass)->ThreadRange(1, NumCPUs());
@@ -553,11 +534,11 @@
 BENCHMARK(Parse_Split_RE2)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_Split_BitState)->ThreadRange(1, NumCPUs());
 
-void Parse_CachedSplit_NFA(int i)         { Parse1Split(i, Parse1CachedNFA); }
-void Parse_CachedSplit_OnePass(int i)     { Parse1Split(i, Parse1CachedOnePass); }
-void Parse_CachedSplit_PCRE(int i)        { Parse1Split(i, Parse1CachedPCRE); }
-void Parse_CachedSplit_RE2(int i)         { Parse1Split(i, Parse1CachedRE2); }
-void Parse_CachedSplit_BitState(int i)         { Parse1Split(i, Parse1CachedBitState); }
+void Parse_CachedSplit_NFA(benchmark::State& state)         { Parse1Split(state, Parse1CachedNFA); }
+void Parse_CachedSplit_OnePass(benchmark::State& state)     { Parse1Split(state, Parse1CachedOnePass); }
+void Parse_CachedSplit_PCRE(benchmark::State& state)        { Parse1Split(state, Parse1CachedPCRE); }
+void Parse_CachedSplit_RE2(benchmark::State& state)         { Parse1Split(state, Parse1CachedRE2); }
+void Parse_CachedSplit_BitState(benchmark::State& state)    { Parse1Split(state, Parse1CachedBitState); }
 
 BENCHMARK(Parse_CachedSplit_NFA)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_CachedSplit_OnePass)->ThreadRange(1, NumCPUs());
@@ -569,17 +550,17 @@
 
 // Benchmark: splitting off leading number field but harder (ambiguous regexp).
 
-void Parse1SplitHard(int iters,
-                  void (*run)(int, const char*, const StringPiece&)) {
-  BenchmarkMemoryUsage();
-  run(iters, "[0-9]+.(.*)", "650-253-0001");
-  SetBenchmarkItemsProcessed(iters);
+void Parse1SplitHard(benchmark::State& state,
+                     void (*run)(benchmark::State&, const char*,
+                                 const StringPiece&)) {
+  run(state, "[0-9]+.(.*)", "650-253-0001");
+  state.SetItemsProcessed(state.iterations());
 }
 
-void Parse_SplitHard_NFA(int i)         { Parse1SplitHard(i, Parse1NFA); }
-void Parse_SplitHard_PCRE(int i)        { Parse1SplitHard(i, Parse1PCRE); }
-void Parse_SplitHard_RE2(int i)         { Parse1SplitHard(i, Parse1RE2); }
-void Parse_SplitHard_BitState(int i)         { Parse1SplitHard(i, Parse1BitState); }
+void Parse_SplitHard_NFA(benchmark::State& state)         { Parse1SplitHard(state, Parse1NFA); }
+void Parse_SplitHard_PCRE(benchmark::State& state)        { Parse1SplitHard(state, Parse1PCRE); }
+void Parse_SplitHard_RE2(benchmark::State& state)         { Parse1SplitHard(state, Parse1RE2); }
+void Parse_SplitHard_BitState(benchmark::State& state)    { Parse1SplitHard(state, Parse1BitState); }
 
 #ifdef USEPCRE
 BENCHMARK(Parse_SplitHard_PCRE)->ThreadRange(1, NumCPUs());
@@ -588,11 +569,11 @@
 BENCHMARK(Parse_SplitHard_BitState)->ThreadRange(1, NumCPUs());
 BENCHMARK(Parse_SplitHard_NFA)->ThreadRange(1, NumCPUs());
 
-void Parse_CachedSplitHard_NFA(int i)       { Parse1SplitHard(i, Parse1CachedNFA); }
-void Parse_CachedSplitHard_PCRE(int i)      { Parse1SplitHard(i, Parse1CachedPCRE); }
-void Parse_CachedSplitHard_RE2(int i)       { Parse1SplitHard(i, Parse1CachedRE2); }
-void Parse_CachedSplitHard_BitState(int i)       { Parse1SplitHard(i, Parse1CachedBitState); }
-void Parse_CachedSplitHard_Backtrack(int i)       { Parse1SplitHard(i, Parse1CachedBacktrack); }
+void Parse_CachedSplitHard_NFA(benchmark::State& state)       { Parse1SplitHard(state, Parse1CachedNFA); }
+void Parse_CachedSplitHard_PCRE(benchmark::State& state)      { Parse1SplitHard(state, Parse1CachedPCRE); }
+void Parse_CachedSplitHard_RE2(benchmark::State& state)       { Parse1SplitHard(state, Parse1CachedRE2); }
+void Parse_CachedSplitHard_BitState(benchmark::State& state)  { Parse1SplitHard(state, Parse1CachedBitState); }
+void Parse_CachedSplitHard_Backtrack(benchmark::State& state) { Parse1SplitHard(state, Parse1CachedBacktrack); }
 
 #ifdef USEPCRE
 BENCHMARK(Parse_CachedSplitHard_PCRE)->ThreadRange(1, NumCPUs());
@@ -604,18 +585,18 @@
 
 // Benchmark: Parse1SplitHard, big text, small match.
 
-void Parse1SplitBig1(int iters,
-                  void (*run)(int, const char*, const StringPiece&)) {
+void Parse1SplitBig1(benchmark::State& state,
+                     void (*run)(benchmark::State&, const char*,
+                                 const StringPiece&)) {
   std::string s;
   s.append(100000, 'x');
   s.append("650-253-0001");
-  BenchmarkMemoryUsage();
-  run(iters, "[0-9]+.(.*)", s);
-  SetBenchmarkItemsProcessed(iters);
+  run(state, "[0-9]+.(.*)", s);
+  state.SetItemsProcessed(state.iterations());
 }
 
-void Parse_CachedSplitBig1_PCRE(int i)      { Parse1SplitBig1(i, SearchParse1CachedPCRE); }
-void Parse_CachedSplitBig1_RE2(int i)       { Parse1SplitBig1(i, SearchParse1CachedRE2); }
+void Parse_CachedSplitBig1_PCRE(benchmark::State& state)      { Parse1SplitBig1(state, SearchParse1CachedPCRE); }
+void Parse_CachedSplitBig1_RE2(benchmark::State& state)       { Parse1SplitBig1(state, SearchParse1CachedRE2); }
 
 #ifdef USEPCRE
 BENCHMARK(Parse_CachedSplitBig1_PCRE)->ThreadRange(1, NumCPUs());
@@ -624,18 +605,18 @@
 
 // Benchmark: Parse1SplitHard, big text, big match.
 
-void Parse1SplitBig2(int iters,
-                  void (*run)(int, const char*, const StringPiece&)) {
+void Parse1SplitBig2(benchmark::State& state,
+                     void (*run)(benchmark::State&, const char*,
+                                 const StringPiece&)) {
   std::string s;
   s.append("650-253-");
   s.append(100000, '0');
-  BenchmarkMemoryUsage();
-  run(iters, "[0-9]+.(.*)", s);
-  SetBenchmarkItemsProcessed(iters);
+  run(state, "[0-9]+.(.*)", s);
+  state.SetItemsProcessed(state.iterations());
 }
 
-void Parse_CachedSplitBig2_PCRE(int i)      { Parse1SplitBig2(i, SearchParse1CachedPCRE); }
-void Parse_CachedSplitBig2_RE2(int i)       { Parse1SplitBig2(i, SearchParse1CachedRE2); }
+void Parse_CachedSplitBig2_PCRE(benchmark::State& state)      { Parse1SplitBig2(state, SearchParse1CachedPCRE); }
+void Parse_CachedSplitBig2_RE2(benchmark::State& state)       { Parse1SplitBig2(state, SearchParse1CachedRE2); }
 
 #ifdef USEPCRE
 BENCHMARK(Parse_CachedSplitBig2_PCRE)->ThreadRange(1, NumCPUs());
@@ -645,16 +626,16 @@
 // Benchmark: measure time required to parse (but not execute)
 // a simple regular expression.
 
-void ParseRegexp(int iters, const std::string& regexp) {
-  for (int i = 0; i < iters; i++) {
+void ParseRegexp(benchmark::State& state, const std::string& regexp) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     re->Decref();
   }
 }
 
-void SimplifyRegexp(int iters, const std::string& regexp) {
-  for (int i = 0; i < iters; i++) {
+void SimplifyRegexp(benchmark::State& state, const std::string& regexp) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Regexp* sre = re->Simplify();
@@ -664,17 +645,17 @@
   }
 }
 
-void NullWalkRegexp(int iters, const std::string& regexp) {
+void NullWalkRegexp(benchmark::State& state, const std::string& regexp) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     re->NullWalk();
   }
   re->Decref();
 }
 
-void SimplifyCompileRegexp(int iters, const std::string& regexp) {
-  for (int i = 0; i < iters; i++) {
+void SimplifyCompileRegexp(benchmark::State& state, const std::string& regexp) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Regexp* sre = re->Simplify();
@@ -687,8 +668,8 @@
   }
 }
 
-void CompileRegexp(int iters, const std::string& regexp) {
-  for (int i = 0; i < iters; i++) {
+void CompileRegexp(benchmark::State& state, const std::string& regexp) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -698,10 +679,10 @@
   }
 }
 
-void CompileToProg(int iters, const std::string& regexp) {
+void CompileToProg(benchmark::State& state, const std::string& regexp) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     Prog* prog = re->CompileToProg(0);
     CHECK(prog);
     delete prog;
@@ -709,36 +690,36 @@
   re->Decref();
 }
 
-void CompileByteMap(int iters, const std::string& regexp) {
+void CompileByteMap(benchmark::State& state, const std::string& regexp) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     prog->ComputeByteMap();
   }
   delete prog;
   re->Decref();
 }
 
-void CompilePCRE(int iters, const std::string& regexp) {
-  for (int i = 0; i < iters; i++) {
+void CompilePCRE(benchmark::State& state, const std::string& regexp) {
+  for (auto _ : state) {
     PCRE re(regexp, PCRE::UTF8);
     CHECK_EQ(re.error(), "");
   }
 }
 
-void CompileRE2(int iters, const std::string& regexp) {
-  for (int i = 0; i < iters; i++) {
+void CompileRE2(benchmark::State& state, const std::string& regexp) {
+  for (auto _ : state) {
     RE2 re(regexp);
     CHECK_EQ(re.error(), "");
   }
 }
 
-void RunBuild(int iters, const std::string& regexp,
-              void (*run)(int, const std::string&)) {
-  run(iters, regexp);
-  SetBenchmarkItemsProcessed(iters);
+void RunBuild(benchmark::State& state, const std::string& regexp,
+              void (*run)(benchmark::State&, const std::string&)) {
+  run(state, regexp);
+  state.SetItemsProcessed(state.iterations());
 }
 
 }  // namespace re2
@@ -747,15 +728,15 @@
 
 namespace re2 {
 
-void BM_PCRE_Compile(int i)      { RunBuild(i, FLAGS_compile_regexp, CompilePCRE); }
-void BM_Regexp_Parse(int i)      { RunBuild(i, FLAGS_compile_regexp, ParseRegexp); }
-void BM_Regexp_Simplify(int i)   { RunBuild(i, FLAGS_compile_regexp, SimplifyRegexp); }
-void BM_CompileToProg(int i)     { RunBuild(i, FLAGS_compile_regexp, CompileToProg); }
-void BM_CompileByteMap(int i)     { RunBuild(i, FLAGS_compile_regexp, CompileByteMap); }
-void BM_Regexp_Compile(int i)    { RunBuild(i, FLAGS_compile_regexp, CompileRegexp); }
-void BM_Regexp_SimplifyCompile(int i)   { RunBuild(i, FLAGS_compile_regexp, SimplifyCompileRegexp); }
-void BM_Regexp_NullWalk(int i)   { RunBuild(i, FLAGS_compile_regexp, NullWalkRegexp); }
-void BM_RE2_Compile(int i)       { RunBuild(i, FLAGS_compile_regexp, CompileRE2); }
+void BM_PCRE_Compile(benchmark::State& state)             { RunBuild(state, FLAGS_compile_regexp, CompilePCRE); }
+void BM_Regexp_Parse(benchmark::State& state)             { RunBuild(state, FLAGS_compile_regexp, ParseRegexp); }
+void BM_Regexp_Simplify(benchmark::State& state)          { RunBuild(state, FLAGS_compile_regexp, SimplifyRegexp); }
+void BM_CompileToProg(benchmark::State& state)            { RunBuild(state, FLAGS_compile_regexp, CompileToProg); }
+void BM_CompileByteMap(benchmark::State& state)           { RunBuild(state, FLAGS_compile_regexp, CompileByteMap); }
+void BM_Regexp_Compile(benchmark::State& state)           { RunBuild(state, FLAGS_compile_regexp, CompileRegexp); }
+void BM_Regexp_SimplifyCompile(benchmark::State& state)   { RunBuild(state, FLAGS_compile_regexp, SimplifyCompileRegexp); }
+void BM_Regexp_NullWalk(benchmark::State& state)          { RunBuild(state, FLAGS_compile_regexp, NullWalkRegexp); }
+void BM_RE2_Compile(benchmark::State& state)              { RunBuild(state, FLAGS_compile_regexp, CompileRE2); }
 
 #ifdef USEPCRE
 BENCHMARK(BM_PCRE_Compile)->ThreadRange(1, NumCPUs());
@@ -771,22 +752,20 @@
 
 // Makes text of size nbytes, then calls run to search
 // the text for regexp iters times.
-void SearchPhone(int iters, int nbytes, ParseImpl* search) {
-  StopBenchmarkTiming();
+void SearchPhone(benchmark::State& state, ParseImpl* search) {
   std::string s;
-  MakeText(&s, nbytes);
+  MakeText(&s, state.range());
   s.append("(650) 253-0001");
-  BenchmarkMemoryUsage();
-  StartBenchmarkTiming();
-  search(iters, "(\\d{3}-|\\(\\d{3}\\)\\s+)(\\d{3}-\\d{4})", s);
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iters)*nbytes);
+  search(state, "(\\d{3}-|\\(\\d{3}\\)\\s+)(\\d{3}-\\d{4})", s);
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
-void SearchPhone_CachedPCRE(int i, int n) {
-  SearchPhone(i, n, SearchParse2CachedPCRE);
+void SearchPhone_CachedPCRE(benchmark::State& state) {
+  SearchPhone(state, SearchParse2CachedPCRE);
 }
-void SearchPhone_CachedRE2(int i, int n) {
-  SearchPhone(i, n, SearchParse2CachedRE2);
+
+void SearchPhone_CachedRE2(benchmark::State& state) {
+  SearchPhone(state, SearchParse2CachedRE2);
 }
 
 #ifdef USEPCRE
@@ -881,9 +860,10 @@
 // Expect_match says whether the regexp should be found.
 // Anchored says whether to run an anchored search.
 
-void SearchDFA(int iters, const char* regexp, const StringPiece& text,
-            Prog::Anchor anchor, bool expect_match) {
-  for (int i = 0; i < iters; i++) {
+void SearchDFA(benchmark::State& state, const char* regexp,
+               const StringPiece& text, Prog::Anchor anchor,
+               bool expect_match) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -898,9 +878,10 @@
   }
 }
 
-void SearchNFA(int iters, const char* regexp, const StringPiece& text,
-            Prog::Anchor anchor, bool expect_match) {
-  for (int i = 0; i < iters; i++) {
+void SearchNFA(benchmark::State& state, const char* regexp,
+               const StringPiece& text, Prog::Anchor anchor,
+               bool expect_match) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -913,9 +894,10 @@
   }
 }
 
-void SearchOnePass(int iters, const char* regexp, const StringPiece& text,
-            Prog::Anchor anchor, bool expect_match) {
-  for (int i = 0; i < iters; i++) {
+void SearchOnePass(benchmark::State& state, const char* regexp,
+                   const StringPiece& text, Prog::Anchor anchor,
+                   bool expect_match) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -928,9 +910,10 @@
   }
 }
 
-void SearchBitState(int iters, const char* regexp, const StringPiece& text,
-            Prog::Anchor anchor, bool expect_match) {
-  for (int i = 0; i < iters; i++) {
+void SearchBitState(benchmark::State& state, const char* regexp,
+                    const StringPiece& text, Prog::Anchor anchor,
+                    bool expect_match) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -943,9 +926,10 @@
   }
 }
 
-void SearchPCRE(int iters, const char* regexp, const StringPiece& text,
-                Prog::Anchor anchor, bool expect_match) {
-  for (int i = 0; i < iters; i++) {
+void SearchPCRE(benchmark::State& state, const char* regexp,
+                const StringPiece& text, Prog::Anchor anchor,
+                bool expect_match) {
+  for (auto _ : state) {
     PCRE re(regexp, PCRE::UTF8);
     CHECK_EQ(re.error(), "");
     if (anchor == Prog::kAnchored)
@@ -955,9 +939,10 @@
   }
 }
 
-void SearchRE2(int iters, const char* regexp, const StringPiece& text,
-               Prog::Anchor anchor, bool expect_match) {
-  for (int i = 0; i < iters; i++) {
+void SearchRE2(benchmark::State& state, const char* regexp,
+               const StringPiece& text, Prog::Anchor anchor,
+               bool expect_match) {
+  for (auto _ : state) {
     RE2 re(regexp);
     CHECK_EQ(re.error(), "");
     if (anchor == Prog::kAnchored)
@@ -971,13 +956,14 @@
 // regexp parsing and compiling once.  This lets us measure
 // search time without the per-regexp overhead.
 
-void SearchCachedDFA(int iters, const char* regexp, const StringPiece& text,
-                     Prog::Anchor anchor, bool expect_match) {
+void SearchCachedDFA(benchmark::State& state, const char* regexp,
+                     const StringPiece& text, Prog::Anchor anchor,
+                     bool expect_match) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(1LL<<31);
   CHECK(prog);
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     bool failed = false;
     CHECK_EQ(prog->SearchDFA(text, StringPiece(), anchor, Prog::kFirstMatch,
                              NULL, &failed, NULL),
@@ -988,13 +974,14 @@
   re->Decref();
 }
 
-void SearchCachedNFA(int iters, const char* regexp, const StringPiece& text,
-                     Prog::Anchor anchor, bool expect_match) {
+void SearchCachedNFA(benchmark::State& state, const char* regexp,
+                     const StringPiece& text, Prog::Anchor anchor,
+                     bool expect_match) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     CHECK_EQ(prog->SearchNFA(text, StringPiece(), anchor, Prog::kFirstMatch,
                              NULL, 0),
              expect_match);
@@ -1003,39 +990,44 @@
   re->Decref();
 }
 
-void SearchCachedOnePass(int iters, const char* regexp, const StringPiece& text,
-                     Prog::Anchor anchor, bool expect_match) {
+void SearchCachedOnePass(benchmark::State& state, const char* regexp,
+                         const StringPiece& text, Prog::Anchor anchor,
+                         bool expect_match) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   CHECK(prog->IsOnePass());
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK_EQ(prog->SearchOnePass(text, text, anchor, Prog::kFirstMatch, NULL, 0),
              expect_match);
+  }
   delete prog;
   re->Decref();
 }
 
-void SearchCachedBitState(int iters, const char* regexp, const StringPiece& text,
-                     Prog::Anchor anchor, bool expect_match) {
+void SearchCachedBitState(benchmark::State& state, const char* regexp,
+                          const StringPiece& text, Prog::Anchor anchor,
+                          bool expect_match) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   CHECK(prog->CanBitState());
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK_EQ(prog->SearchBitState(text, text, anchor, Prog::kFirstMatch, NULL, 0),
              expect_match);
+  }
   delete prog;
   re->Decref();
 }
 
-void SearchCachedPCRE(int iters, const char* regexp, const StringPiece& text,
-                     Prog::Anchor anchor, bool expect_match) {
+void SearchCachedPCRE(benchmark::State& state, const char* regexp,
+                      const StringPiece& text, Prog::Anchor anchor,
+                      bool expect_match) {
   PCRE re(regexp, PCRE::UTF8);
   CHECK_EQ(re.error(), "");
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     if (anchor == Prog::kAnchored)
       CHECK_EQ(PCRE::FullMatch(text, re), expect_match);
     else
@@ -1043,11 +1035,12 @@
   }
 }
 
-void SearchCachedRE2(int iters, const char* regexp, const StringPiece& text,
-                     Prog::Anchor anchor, bool expect_match) {
+void SearchCachedRE2(benchmark::State& state, const char* regexp,
+                     const StringPiece& text, Prog::Anchor anchor,
+                     bool expect_match) {
   RE2 re(regexp);
   CHECK_EQ(re.error(), "");
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     if (anchor == Prog::kAnchored)
       CHECK_EQ(RE2::FullMatch(text, re), expect_match);
     else
@@ -1055,12 +1048,12 @@
   }
 }
 
-
 // Runs implementation to full match regexp against text,
 // extracting three submatches.  Expects match always.
 
-void Parse3NFA(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse3NFA(benchmark::State& state, const char* regexp,
+               const StringPiece& text) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -1073,8 +1066,9 @@
   }
 }
 
-void Parse3OnePass(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse3OnePass(benchmark::State& state, const char* regexp,
+                   const StringPiece& text) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -1087,8 +1081,9 @@
   }
 }
 
-void Parse3BitState(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse3BitState(benchmark::State& state, const char* regexp,
+                    const StringPiece& text) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -1101,8 +1096,9 @@
   }
 }
 
-void Parse3Backtrack(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse3Backtrack(benchmark::State& state, const char* regexp,
+                     const StringPiece& text) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -1114,8 +1110,9 @@
   }
 }
 
-void Parse3PCRE(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse3PCRE(benchmark::State& state, const char* regexp,
+                const StringPiece& text) {
+  for (auto _ : state) {
     PCRE re(regexp, PCRE::UTF8);
     CHECK_EQ(re.error(), "");
     StringPiece sp1, sp2, sp3;
@@ -1123,8 +1120,9 @@
   }
 }
 
-void Parse3RE2(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse3RE2(benchmark::State& state, const char* regexp,
+               const StringPiece& text) {
+  for (auto _ : state) {
     RE2 re(regexp);
     CHECK_EQ(re.error(), "");
     StringPiece sp1, sp2, sp3;
@@ -1132,13 +1130,14 @@
   }
 }
 
-void Parse3CachedNFA(int iters, const char* regexp, const StringPiece& text) {
+void Parse3CachedNFA(benchmark::State& state, const char* regexp,
+                     const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   StringPiece sp[4];  // 4 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     CHECK(prog->SearchNFA(text, StringPiece(), Prog::kAnchored,
                           Prog::kFullMatch, sp, 4));
   }
@@ -1146,68 +1145,76 @@
   re->Decref();
 }
 
-void Parse3CachedOnePass(int iters, const char* regexp, const StringPiece& text) {
+void Parse3CachedOnePass(benchmark::State& state, const char* regexp,
+                         const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   CHECK(prog->IsOnePass());
   StringPiece sp[4];  // 4 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK(prog->SearchOnePass(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 4));
+  }
   delete prog;
   re->Decref();
 }
 
-void Parse3CachedBitState(int iters, const char* regexp, const StringPiece& text) {
+void Parse3CachedBitState(benchmark::State& state, const char* regexp,
+                          const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   CHECK(prog->CanBitState());
   StringPiece sp[4];  // 4 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK(prog->SearchBitState(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 4));
+  }
   delete prog;
   re->Decref();
 }
 
-void Parse3CachedBacktrack(int iters, const char* regexp, const StringPiece& text) {
+void Parse3CachedBacktrack(benchmark::State& state, const char* regexp,
+                           const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   StringPiece sp[4];  // 4 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK(prog->UnsafeSearchBacktrack(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 4));
+  }
   delete prog;
   re->Decref();
 }
 
-void Parse3CachedPCRE(int iters, const char* regexp, const StringPiece& text) {
+void Parse3CachedPCRE(benchmark::State& state, const char* regexp,
+                      const StringPiece& text) {
   PCRE re(regexp, PCRE::UTF8);
   CHECK_EQ(re.error(), "");
   StringPiece sp1, sp2, sp3;
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     CHECK(PCRE::FullMatch(text, re, &sp1, &sp2, &sp3));
   }
 }
 
-void Parse3CachedRE2(int iters, const char* regexp, const StringPiece& text) {
+void Parse3CachedRE2(benchmark::State& state, const char* regexp,
+                     const StringPiece& text) {
   RE2 re(regexp);
   CHECK_EQ(re.error(), "");
   StringPiece sp1, sp2, sp3;
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     CHECK(RE2::FullMatch(text, re, &sp1, &sp2, &sp3));
   }
 }
 
-
 // Runs implementation to full match regexp against text,
 // extracting three submatches.  Expects match always.
 
-void Parse1NFA(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse1NFA(benchmark::State& state, const char* regexp,
+               const StringPiece& text) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -1220,8 +1227,9 @@
   }
 }
 
-void Parse1OnePass(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse1OnePass(benchmark::State& state, const char* regexp,
+                   const StringPiece& text) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -1234,8 +1242,9 @@
   }
 }
 
-void Parse1BitState(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse1BitState(benchmark::State& state, const char* regexp,
+                    const StringPiece& text) {
+  for (auto _ : state) {
     Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
     CHECK(re);
     Prog* prog = re->CompileToProg(0);
@@ -1248,8 +1257,9 @@
   }
 }
 
-void Parse1PCRE(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse1PCRE(benchmark::State& state, const char* regexp,
+                const StringPiece& text) {
+  for (auto _ : state) {
     PCRE re(regexp, PCRE::UTF8);
     CHECK_EQ(re.error(), "");
     StringPiece sp1;
@@ -1257,8 +1267,9 @@
   }
 }
 
-void Parse1RE2(int iters, const char* regexp, const StringPiece& text) {
-  for (int i = 0; i < iters; i++) {
+void Parse1RE2(benchmark::State& state, const char* regexp,
+               const StringPiece& text) {
+  for (auto _ : state) {
     RE2 re(regexp);
     CHECK_EQ(re.error(), "");
     StringPiece sp1;
@@ -1266,13 +1277,14 @@
   }
 }
 
-void Parse1CachedNFA(int iters, const char* regexp, const StringPiece& text) {
+void Parse1CachedNFA(benchmark::State& state, const char* regexp,
+                     const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   StringPiece sp[2];  // 2 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     CHECK(prog->SearchNFA(text, StringPiece(), Prog::kAnchored,
                           Prog::kFullMatch, sp, 2));
   }
@@ -1280,112 +1292,120 @@
   re->Decref();
 }
 
-void Parse1CachedOnePass(int iters, const char* regexp, const StringPiece& text) {
+void Parse1CachedOnePass(benchmark::State& state, const char* regexp,
+                         const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   CHECK(prog->IsOnePass());
   StringPiece sp[2];  // 2 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK(prog->SearchOnePass(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 2));
+  }
   delete prog;
   re->Decref();
 }
 
-void Parse1CachedBitState(int iters, const char* regexp, const StringPiece& text) {
+void Parse1CachedBitState(benchmark::State& state, const char* regexp,
+                          const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   CHECK(prog->CanBitState());
   StringPiece sp[2];  // 2 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK(prog->SearchBitState(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 2));
+  }
   delete prog;
   re->Decref();
 }
 
-void Parse1CachedBacktrack(int iters, const char* regexp, const StringPiece& text) {
+void Parse1CachedBacktrack(benchmark::State& state, const char* regexp,
+                           const StringPiece& text) {
   Regexp* re = Regexp::Parse(regexp, Regexp::LikePerl, NULL);
   CHECK(re);
   Prog* prog = re->CompileToProg(0);
   CHECK(prog);
   StringPiece sp[2];  // 2 because sp[0] is whole match.
-  for (int i = 0; i < iters; i++)
+  for (auto _ : state) {
     CHECK(prog->UnsafeSearchBacktrack(text, text, Prog::kAnchored, Prog::kFullMatch, sp, 2));
+  }
   delete prog;
   re->Decref();
 }
 
-void Parse1CachedPCRE(int iters, const char* regexp, const StringPiece& text) {
+void Parse1CachedPCRE(benchmark::State& state, const char* regexp,
+                      const StringPiece& text) {
   PCRE re(regexp, PCRE::UTF8);
   CHECK_EQ(re.error(), "");
   StringPiece sp1;
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     CHECK(PCRE::FullMatch(text, re, &sp1));
   }
 }
 
-void Parse1CachedRE2(int iters, const char* regexp, const StringPiece& text) {
+void Parse1CachedRE2(benchmark::State& state, const char* regexp,
+                     const StringPiece& text) {
   RE2 re(regexp);
   CHECK_EQ(re.error(), "");
   StringPiece sp1;
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     CHECK(RE2::FullMatch(text, re, &sp1));
   }
 }
 
-void SearchParse2CachedPCRE(int iters, const char* regexp,
+void SearchParse2CachedPCRE(benchmark::State& state, const char* regexp,
                             const StringPiece& text) {
   PCRE re(regexp, PCRE::UTF8);
   CHECK_EQ(re.error(), "");
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     StringPiece sp1, sp2;
     CHECK(PCRE::PartialMatch(text, re, &sp1, &sp2));
   }
 }
 
-void SearchParse2CachedRE2(int iters, const char* regexp,
+void SearchParse2CachedRE2(benchmark::State& state, const char* regexp,
                            const StringPiece& text) {
   RE2 re(regexp);
   CHECK_EQ(re.error(), "");
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     StringPiece sp1, sp2;
     CHECK(RE2::PartialMatch(text, re, &sp1, &sp2));
   }
 }
 
-void SearchParse1CachedPCRE(int iters, const char* regexp,
+void SearchParse1CachedPCRE(benchmark::State& state, const char* regexp,
                             const StringPiece& text) {
   PCRE re(regexp, PCRE::UTF8);
   CHECK_EQ(re.error(), "");
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     StringPiece sp1;
     CHECK(PCRE::PartialMatch(text, re, &sp1));
   }
 }
 
-void SearchParse1CachedRE2(int iters, const char* regexp,
+void SearchParse1CachedRE2(benchmark::State& state, const char* regexp,
                            const StringPiece& text) {
   RE2 re(regexp);
   CHECK_EQ(re.error(), "");
-  for (int i = 0; i < iters; i++) {
+  for (auto _ : state) {
     StringPiece sp1;
     CHECK(RE2::PartialMatch(text, re, &sp1));
   }
 }
 
-void EmptyPartialMatchPCRE(int n) {
+void EmptyPartialMatchPCRE(benchmark::State& state) {
   PCRE re("");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     PCRE::PartialMatch("", re);
   }
 }
 
-void EmptyPartialMatchRE2(int n) {
+void EmptyPartialMatchRE2(benchmark::State& state) {
   RE2 re("");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     RE2::PartialMatch("", re);
   }
 }
@@ -1394,16 +1414,16 @@
 #endif
 BENCHMARK(EmptyPartialMatchRE2)->ThreadRange(1, NumCPUs());
 
-void SimplePartialMatchPCRE(int n) {
+void SimplePartialMatchPCRE(benchmark::State& state) {
   PCRE re("abcdefg");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     PCRE::PartialMatch("abcdefg", re);
   }
 }
 
-void SimplePartialMatchRE2(int n) {
+void SimplePartialMatchRE2(benchmark::State& state) {
   RE2 re("abcdefg");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     RE2::PartialMatch("abcdefg", re);
   }
 }
@@ -1416,18 +1436,18 @@
   "GET /asdfhjasdhfasdlfhasdflkjasdfkljasdhflaskdjhf"
   "alksdjfhasdlkfhasdlkjfhasdljkfhadsjklf HTTP/1.1";
 
-void HTTPPartialMatchPCRE(int n) {
+void HTTPPartialMatchPCRE(benchmark::State& state) {
   StringPiece a;
   PCRE re("(?-s)^(?:GET|POST) +([^ ]+) HTTP");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     PCRE::PartialMatch(http_text, re, &a);
   }
 }
 
-void HTTPPartialMatchRE2(int n) {
+void HTTPPartialMatchRE2(benchmark::State& state) {
   StringPiece a;
   RE2 re("(?-s)^(?:GET|POST) +([^ ]+) HTTP");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     RE2::PartialMatch(http_text, re, &a);
   }
 }
@@ -1440,18 +1460,18 @@
 static std::string smallhttp_text =
   "GET /abc HTTP/1.1";
 
-void SmallHTTPPartialMatchPCRE(int n) {
+void SmallHTTPPartialMatchPCRE(benchmark::State& state) {
   StringPiece a;
   PCRE re("(?-s)^(?:GET|POST) +([^ ]+) HTTP");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     PCRE::PartialMatch(smallhttp_text, re, &a);
   }
 }
 
-void SmallHTTPPartialMatchRE2(int n) {
+void SmallHTTPPartialMatchRE2(benchmark::State& state) {
   StringPiece a;
   RE2 re("(?-s)^(?:GET|POST) +([^ ]+) HTTP");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     RE2::PartialMatch(smallhttp_text, re, &a);
   }
 }
@@ -1461,18 +1481,18 @@
 #endif
 BENCHMARK(SmallHTTPPartialMatchRE2)->ThreadRange(1, NumCPUs());
 
-void DotMatchPCRE(int n) {
+void DotMatchPCRE(benchmark::State& state) {
   StringPiece a;
   PCRE re("(?-s)^(.+)");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     PCRE::PartialMatch(http_text, re, &a);
   }
 }
 
-void DotMatchRE2(int n) {
+void DotMatchRE2(benchmark::State& state) {
   StringPiece a;
   RE2 re("(?-s)^(.+)");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     RE2::PartialMatch(http_text, re, &a);
   }
 }
@@ -1482,18 +1502,18 @@
 #endif
 BENCHMARK(DotMatchRE2)->ThreadRange(1, NumCPUs());
 
-void ASCIIMatchPCRE(int n) {
+void ASCIIMatchPCRE(benchmark::State& state) {
   StringPiece a;
   PCRE re("(?-s)^([ -~]+)");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     PCRE::PartialMatch(http_text, re, &a);
   }
 }
 
-void ASCIIMatchRE2(int n) {
+void ASCIIMatchRE2(benchmark::State& state) {
   StringPiece a;
   RE2 re("(?-s)^([ -~]+)");
-  for (int i = 0; i < n; i++) {
+  for (auto _ : state) {
     RE2::PartialMatch(http_text, re, &a);
   }
 }
@@ -1503,40 +1523,36 @@
 #endif
 BENCHMARK(ASCIIMatchRE2)->ThreadRange(1, NumCPUs());
 
-void FullMatchPCRE(int iter, int n, const char *regexp) {
-  StopBenchmarkTiming();
+void FullMatchPCRE(benchmark::State& state, const char *regexp) {
   std::string s;
-  MakeText(&s, n);
+  MakeText(&s, state.range());
   s += "ABCDEFGHIJ";
-  BenchmarkMemoryUsage();
   PCRE re(regexp);
-  StartBenchmarkTiming();
-  for (int i = 0; i < iter; i++)
+  for (auto _ : state) {
     CHECK(PCRE::FullMatch(s, re));
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iter)*n);
+  }
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
-void FullMatchRE2(int iter, int n, const char *regexp) {
-  StopBenchmarkTiming();
+void FullMatchRE2(benchmark::State& state, const char *regexp) {
   std::string s;
-  MakeText(&s, n);
+  MakeText(&s, state.range());
   s += "ABCDEFGHIJ";
-  BenchmarkMemoryUsage();
   RE2 re(regexp, RE2::Latin1);
-  StartBenchmarkTiming();
-  for (int i = 0; i < iter; i++)
+  for (auto _ : state) {
     CHECK(RE2::FullMatch(s, re));
-  SetBenchmarkBytesProcessed(static_cast<int64_t>(iter)*n);
+  }
+  state.SetBytesProcessed(state.iterations() * state.range());
 }
 
-void FullMatch_DotStar_CachedPCRE(int i, int n) { FullMatchPCRE(i, n, "(?s).*"); }
-void FullMatch_DotStar_CachedRE2(int i, int n)  { FullMatchRE2(i, n, "(?s).*"); }
+void FullMatch_DotStar_CachedPCRE(benchmark::State& state) { FullMatchPCRE(state, "(?s).*"); }
+void FullMatch_DotStar_CachedRE2(benchmark::State& state)  { FullMatchRE2(state, "(?s).*"); }
 
-void FullMatch_DotStarDollar_CachedPCRE(int i, int n) { FullMatchPCRE(i, n, "(?s).*$"); }
-void FullMatch_DotStarDollar_CachedRE2(int i, int n)  { FullMatchRE2(i, n, "(?s).*$"); }
+void FullMatch_DotStarDollar_CachedPCRE(benchmark::State& state) { FullMatchPCRE(state, "(?s).*$"); }
+void FullMatch_DotStarDollar_CachedRE2(benchmark::State& state)  { FullMatchRE2(state, "(?s).*$"); }
 
-void FullMatch_DotStarCapture_CachedPCRE(int i, int n) { FullMatchPCRE(i, n, "(?s)((.*)()()($))"); }
-void FullMatch_DotStarCapture_CachedRE2(int i, int n)  { FullMatchRE2(i, n, "(?s)((.*)()()($))"); }
+void FullMatch_DotStarCapture_CachedPCRE(benchmark::State& state) { FullMatchPCRE(state, "(?s)((.*)()()($))"); }
+void FullMatch_DotStarCapture_CachedRE2(benchmark::State& state)  { FullMatchRE2(state, "(?s)((.*)()()($))"); }
 
 #ifdef USEPCRE
 BENCHMARK_RANGE(FullMatch_DotStar_CachedPCRE, 8, 2<<20);
@@ -1553,29 +1569,27 @@
 #endif
 BENCHMARK_RANGE(FullMatch_DotStarCapture_CachedRE2,  8, 2<<20);
 
-void PossibleMatchRangeCommon(int iter, const char* regexp) {
-  StopBenchmarkTiming();
+void PossibleMatchRangeCommon(benchmark::State& state, const char* regexp) {
   RE2 re(regexp);
-  StartBenchmarkTiming();
   std::string min;
   std::string max;
   const int kMaxLen = 16;
-  for (int i = 0; i < iter; i++) {
+  for (auto _ : state) {
     CHECK(re.PossibleMatchRange(&min, &max, kMaxLen));
   }
 }
 
-void PossibleMatchRange_Trivial(int i) {
-  PossibleMatchRangeCommon(i, ".*");
+void PossibleMatchRange_Trivial(benchmark::State& state) {
+  PossibleMatchRangeCommon(state, ".*");
 }
-void PossibleMatchRange_Complex(int i) {
-  PossibleMatchRangeCommon(i, "^abc[def]?[gh]{1,2}.*");
+void PossibleMatchRange_Complex(benchmark::State& state) {
+  PossibleMatchRangeCommon(state, "^abc[def]?[gh]{1,2}.*");
 }
-void PossibleMatchRange_Prefix(int i) {
-  PossibleMatchRangeCommon(i, "^some_random_prefix.*");
+void PossibleMatchRange_Prefix(benchmark::State& state) {
+  PossibleMatchRangeCommon(state, "^some_random_prefix.*");
 }
-void PossibleMatchRange_NoProg(int i) {
-  PossibleMatchRangeCommon(i, "^some_random_string$");
+void PossibleMatchRange_NoProg(benchmark::State& state) {
+  PossibleMatchRangeCommon(state, "^some_random_string$");
 }
 
 BENCHMARK(PossibleMatchRange_Trivial);
diff --git a/util/benchmark.h b/util/benchmark.h
index 1e7ad8b..fb81cc4 100644
--- a/util/benchmark.h
+++ b/util/benchmark.h
@@ -100,28 +100,6 @@
 
 class Benchmark {
  public:
-  Benchmark(const char* name, void (*func)(int))
-      : name_(name),
-        func_([func](int iters, int arg) {
-          func(iters);
-        }),
-        lo_(0),
-        hi_(0),
-        has_arg_(false) {
-    Register();
-  }
-
-  Benchmark(const char* name, void (*func)(int, int), int lo, int hi)
-      : name_(name),
-        func_([func](int iters, int arg) {
-          func(iters, arg);
-        }),
-        lo_(lo),
-        hi_(hi),
-        has_arg_(true) {
-    Register();
-  }
-
   Benchmark(const char* name, void (*func)(benchmark::State&))
       : name_(name),
         func_([func](int iters, int arg) {