Allow wildcards to match arg values.

Change-Id: I38230b500bb8f8f69af0d7c740855a401cd12898
diff --git a/benchmarks/Benchmark.cpp b/benchmarks/Benchmark.cpp
index eea304f..5ca1d47 100644
--- a/benchmarks/Benchmark.cpp
+++ b/benchmarks/Benchmark.cpp
@@ -39,40 +39,45 @@
   return static_cast<uint64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
 }
 
+bool Benchmark::header_printed_;
+
 std::vector<Benchmark*>& Benchmark::List() {
   static std::vector<Benchmark*> list;
   return list;
 }
 
 int Benchmark::MaxNameColumnWidth() {
-  int max = 20;
+  size_t max = 20;
   for (auto& benchmark : List()) {
     max = std::max(max, benchmark->NameColumnWidth());
   }
-  return max;
+  return static_cast<int>(max);
 }
 
-bool Benchmark::RunAll(std::vector<regex_t*>& regs) {
-  bool ran_benchmark = false;
+size_t Benchmark::RunAll(std::vector<regex_t*>& regs) {
+  size_t benchmarks_run = 0;
+  header_printed_ = false;
   for (auto& benchmark : List()) {
-    if (benchmark->ShouldRun(regs)) {
-      if (!ran_benchmark) {
-        printf("%-*s %10s %10s\n", MaxNameColumnWidth(), "", "iterations", "ns/op");
-        ran_benchmark = true;
-      }
-      benchmark->RunAll();
-    }
+    benchmarks_run += benchmark->RunAllArgs(regs);
   }
-  return ran_benchmark;
+  return benchmarks_run;
 }
 
-bool Benchmark::ShouldRun(std::vector<regex_t*>& regs) {
+void Benchmark::PrintHeader() {
+  if (!header_printed_) {
+    printf("%-*s %10s %10s\n", MaxNameColumnWidth(), "", "iterations", "ns/op");
+    header_printed_ = true;
+  }
+}
+
+template <typename T>
+bool BenchmarkT<T>::ShouldRun(std::vector<regex_t*>& regs, T arg) {
   if (regs.empty()) {
     return true;
   }
 
   for (const auto& re : regs) {
-    if (regexec(re, Name().c_str(), 0, NULL, 0) != REG_NOMATCH) {
+    if (regexec(re, GetNameStr(arg).c_str(), 0, NULL, 0) != REG_NOMATCH) {
       return true;
     }
   }
diff --git a/benchmarks/benchmark/Benchmark.h b/benchmarks/benchmark/Benchmark.h
index 16ae5fa..ae5c1a2 100644
--- a/benchmarks/benchmark/Benchmark.h
+++ b/benchmarks/benchmark/Benchmark.h
@@ -34,27 +34,29 @@
 
   virtual std::string Name() = 0;
 
-  virtual void RunAll() = 0;
-
-  bool ShouldRun(std::vector<regex_t*>&);
+  virtual size_t RunAllArgs(std::vector<regex_t*>&) = 0;
 
   void SetBenchmarkBytesProcessed(uint64_t bytes) { bytes_processed_ += bytes; }
   void StopBenchmarkTiming();
   void StartBenchmarkTiming();
 
   // Run all of the benchmarks that have registered.
-  static bool RunAll(std::vector<regex_t*>&);
+  static size_t RunAll(std::vector<regex_t*>&);
 
   static std::vector<Benchmark*>& List();
 
   static int MaxNameColumnWidth();
 
 protected:
-  virtual int NameColumnWidth() = 0;
+  virtual size_t NameColumnWidth() = 0;
 
   uint64_t bytes_processed_;
   uint64_t total_time_ns_;
   uint64_t start_time_ns_;
+
+  static bool header_printed_;
+
+  static void PrintHeader();
 };
 
 template <typename T>
@@ -64,6 +66,7 @@
   virtual ~BenchmarkT() {}
 
 protected:
+  bool ShouldRun(std::vector<regex_t*>&, T arg);
   void RunWithArg(T arg);
   virtual void RunIterations(int, T) = 0;
   virtual std::string GetNameStr(T) = 0;
@@ -75,8 +78,14 @@
   virtual ~BenchmarkWithoutArg() {}
 
 protected:
-  virtual void RunAll() override {
-    RunWithArg(nullptr);
+  virtual size_t RunAllArgs(std::vector<regex_t*>& regs) override {
+    size_t benchmarks_run = 0;
+    if (BenchmarkT<void*>::ShouldRun(regs, nullptr)) {
+      PrintHeader();
+      RunWithArg(nullptr);
+      benchmarks_run++;
+    }
+    return benchmarks_run;
   }
 
   virtual void RunIterations(int iters, void*) override {
@@ -85,8 +94,8 @@
 
   virtual void Run(int) = 0;
 
-  virtual int NameColumnWidth() override {
-    return (int)Name().size();
+  virtual size_t NameColumnWidth() override {
+    return Name().size();
   }
 
   virtual std::string GetNameStr(void *) override;
@@ -104,20 +113,26 @@
   }
 
 protected:
-  virtual int NameColumnWidth() override {
-    int max = 0;
-    for (const auto arg : args_) {
-      max = std::max(max, (int)GetNameStr(arg).size());
+  virtual size_t NameColumnWidth() override {
+    size_t max = 0;
+    for (const auto& arg : args_) {
+      max = std::max(max, GetNameStr(arg).size());
     }
     return max;
   }
 
   std::string GetNameStr(T arg) override;
 
-  virtual void RunAll() override {
-    for (T arg : args_) {
-      BenchmarkT<T>::RunWithArg(arg);
+  virtual size_t RunAllArgs(std::vector<regex_t*>& regs) override {
+    size_t benchmarks_run = 0;
+    for (T& arg : args_) {
+      if (BenchmarkT<T>::ShouldRun(regs, arg)) {
+        Benchmark::PrintHeader();
+        BenchmarkT<T>::RunWithArg(arg);
+        benchmarks_run++;
+      }
     }
+    return benchmarks_run;
   }
 
   virtual void RunIterations(int iters, T arg) override {
diff --git a/benchmarks/main.cpp b/benchmarks/main.cpp
index b6984fc..5bce479 100644
--- a/benchmarks/main.cpp
+++ b/benchmarks/main.cpp
@@ -48,7 +48,7 @@
     regs.push_back(re);
   }
 
-  if (!::testing::Benchmark::RunAll(regs)) {
+  if (::testing::Benchmark::RunAll(regs) == 0) {
     fprintf(stderr, "No matching benchmarks!\n");
     fprintf(stderr, "Available benchmarks:\n");
     for (const auto& benchmark : ::testing::Benchmark::List()) {