Refactor/modularize headers (#2140)

* Split the benchmark monolithic header

* src uses modular headers

* updated tests to use split headers

* clang-format

* clang-format mistake

* fix exports

* suppress warnings on msvc

* fixing double pops and some more missing exports
diff --git a/BUILD.bazel b/BUILD.bazel
index 993b261..8cad9d6 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -49,7 +49,18 @@
     ),
     hdrs = [
         "include/benchmark/benchmark.h",
+        "include/benchmark/benchmark_api.h",
+        "include/benchmark/counter.h",
         "include/benchmark/export.h",
+        "include/benchmark/macros.h",
+        "include/benchmark/managers.h",
+        "include/benchmark/registration.h",
+        "include/benchmark/reporter.h",
+        "include/benchmark/state.h",
+        "include/benchmark/statistics.h",
+        "include/benchmark/sysinfo.h",
+        "include/benchmark/types.h",
+        "include/benchmark/utils.h",
     ],
     copts = select({
         ":windows": MSVC_COPTS,
@@ -89,7 +100,18 @@
     srcs = ["src/benchmark_main.cc"],
     hdrs = [
         "include/benchmark/benchmark.h",
+        "include/benchmark/benchmark_api.h",
+        "include/benchmark/counter.h",
         "include/benchmark/export.h",
+        "include/benchmark/macros.h",
+        "include/benchmark/managers.h",
+        "include/benchmark/registration.h",
+        "include/benchmark/reporter.h",
+        "include/benchmark/state.h",
+        "include/benchmark/statistics.h",
+        "include/benchmark/sysinfo.h",
+        "include/benchmark/types.h",
+        "include/benchmark/utils.h",
     ],
     includes = ["include"],
     visibility = ["//visibility:public"],
diff --git a/README.md b/README.md
index 1d4470e..db99409 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,8 @@
 A library to benchmark code snippets, similar to unit tests. Example:
 
 ```c++
-#include <benchmark/benchmark.h>
+#include <benchmark/registration.h>
+#include <benchmark/state.h>
 
 static void BM_SomeFunction(benchmark::State& state) {
   // Perform setup here
diff --git a/include/benchmark/benchmark.h b/include/benchmark/benchmark.h
index 0963e70..e065db3 100644
--- a/include/benchmark/benchmark.h
+++ b/include/benchmark/benchmark.h
@@ -12,2105 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Support for registering benchmarks for functions.
-
-/* Example usage:
-// Define a function that executes the code to be measured a
-// specified number of times:
-static void BM_StringCreation(benchmark::State& state) {
-  for (auto _ : state)
-    std::string empty_string;
-}
-
-// Register the function as a benchmark
-BENCHMARK(BM_StringCreation);
-
-// Define another benchmark
-static void BM_StringCopy(benchmark::State& state) {
-  std::string x = "hello";
-  for (auto _ : state)
-    std::string copy(x);
-}
-BENCHMARK(BM_StringCopy);
-
-// Augment the main() program to invoke benchmarks if specified
-// via the --benchmark_filter command line flag.  E.g.,
-//       my_unittest --benchmark_filter=all
-//       my_unittest --benchmark_filter=BM_StringCreation
-//       my_unittest --benchmark_filter=String
-//       my_unittest --benchmark_filter='Copy|Creation'
-int main(int argc, char** argv) {
-  benchmark::MaybeReenterWithoutASLR(argc, argv);
-  benchmark::Initialize(&argc, argv);
-  benchmark::RunSpecifiedBenchmarks();
-  benchmark::Shutdown();
-  return 0;
-}
-
-// Sometimes a family of microbenchmarks can be implemented with
-// just one routine that takes an extra argument to specify which
-// one of the family of benchmarks to run.  For example, the following
-// code defines a family of microbenchmarks for measuring the speed
-// of memcpy() calls of different lengths:
-
-static void BM_memcpy(benchmark::State& state) {
-  char* src = new char[state.range(0)]; char* dst = new char[state.range(0)];
-  memset(src, 'x', state.range(0));
-  for (auto _ : state)
-    memcpy(dst, src, state.range(0));
-  state.SetBytesProcessed(state.iterations() * state.range(0));
-  delete[] src; delete[] dst;
-}
-BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);
-
-// The preceding code is quite repetitive, and can be replaced with the
-// following short-hand.  The following invocation will pick a few
-// appropriate arguments in the specified range and will generate a
-// microbenchmark for each such argument.
-BENCHMARK(BM_memcpy)->Range(8, 8<<10);
-
-// You might have a microbenchmark that depends on two inputs.  For
-// example, the following code defines a family of microbenchmarks for
-// measuring the speed of set insertion.
-static void BM_SetInsert(benchmark::State& state) {
-  set<int> data;
-  for (auto _ : state) {
-    state.PauseTiming();
-    data = ConstructRandomSet(state.range(0));
-    state.ResumeTiming();
-    for (int j = 0; j < state.range(1); ++j)
-      data.insert(RandomNumber());
-  }
-}
-BENCHMARK(BM_SetInsert)
-   ->Args({1<<10, 128})
-   ->Args({2<<10, 128})
-   ->Args({4<<10, 128})
-   ->Args({8<<10, 128})
-   ->Args({1<<10, 512})
-   ->Args({2<<10, 512})
-   ->Args({4<<10, 512})
-   ->Args({8<<10, 512});
-
-// The preceding code is quite repetitive, and can be replaced with
-// the following short-hand.  The following macro will pick a few
-// appropriate arguments in the product of the two specified ranges
-// and will generate a microbenchmark for each such pair.
-BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
-
-// For more complex patterns of inputs, passing a custom function
-// to Apply allows programmatic specification of an
-// arbitrary set of arguments to run the microbenchmark on.
-// The following example enumerates a dense range on
-// one parameter, and a sparse range on the second.
-static void CustomArguments(benchmark::Benchmark* b) {
-  for (int i = 0; i <= 10; ++i)
-    for (int j = 32; j <= 1024*1024; j *= 8)
-      b->Args({i, j});
-}
-BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
-
-// Templated microbenchmarks work the same way:
-// Produce then consume 'size' messages 'iters' times
-// Measures throughput in the absence of multiprogramming.
-template <class Q> int BM_Sequential(benchmark::State& state) {
-  Q q;
-  typename Q::value_type v;
-  for (auto _ : state) {
-    for (int i = state.range(0); i--; )
-      q.push(v);
-    for (int e = state.range(0); e--; )
-      q.Wait(&v);
-  }
-  // actually messages, not bytes:
-  state.SetBytesProcessed(state.iterations() * state.range(0));
-}
-BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
-
-Use `Benchmark::MinTime(double t)` to set the minimum time used to run the
-benchmark. This option overrides the `benchmark_min_time` flag.
-
-void BM_test(benchmark::State& state) {
- ... body ...
-}
-BENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds.
-
-In a multithreaded test, it is guaranteed that none of the threads will start
-until all have reached the loop start, and all will have finished before any
-thread exits the loop body. As such, any global setup or teardown you want to
-do can be wrapped in a check against the thread index:
-
-static void BM_MultiThreaded(benchmark::State& state) {
-  if (state.thread_index() == 0) {
-    // Setup code here.
-  }
-  for (auto _ : state) {
-    // Run the test as normal.
-  }
-  if (state.thread_index() == 0) {
-    // Teardown code here.
-  }
-}
-BENCHMARK(BM_MultiThreaded)->Threads(4);
-
-
-If a benchmark runs a few milliseconds it may be hard to visually compare the
-measured times, since the output data is given in nanoseconds per default. In
-order to manually set the time unit, you can specify it manually:
-
-BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
-*/
-
 #ifndef BENCHMARK_BENCHMARK_H_
 #define BENCHMARK_BENCHMARK_H_
 
-#include <stdint.h>
-
-#include <algorithm>
-#include <atomic>
-#include <cassert>
-#include <cstddef>
-#include <functional>
-#include <iosfwd>
-#include <limits>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "benchmark/export.h"
-
-#if defined(_MSC_VER)
-#include <intrin.h>  // for _ReadWriteBarrier
-#endif
-
-#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
-  TypeName(const TypeName&) = delete;                \
-  TypeName& operator=(const TypeName&) = delete
-
-#ifdef BENCHMARK_HAS_CXX17
-#define BENCHMARK_UNUSED [[maybe_unused]]
-#elif defined(__GNUC__) || defined(__clang__)
-#define BENCHMARK_UNUSED __attribute__((unused))
-#else
-#define BENCHMARK_UNUSED
-#endif
-
-// Used to annotate functions, methods and classes so they
-// are not optimized by the compiler. Useful for tests
-// where you expect loops to stay in place churning cycles
-#if defined(__clang__)
-#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))
-#elif defined(__GNUC__) || defined(__GNUG__)
-#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))
-#else
-// MSVC & Intel do not have a no-optimize attribute, only line pragmas
-#define BENCHMARK_DONT_OPTIMIZE
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
-#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
-#elif defined(_MSC_VER) && !defined(__clang__)
-#define BENCHMARK_ALWAYS_INLINE __forceinline
-#define __func__ __FUNCTION__
-#else
-#define BENCHMARK_ALWAYS_INLINE
-#endif
-
-#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
-#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
-
-// clang-format off
-#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || defined(__clang__)
-#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
-#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
-#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
-  _Pragma("GCC diagnostic push")             \
-  _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
-#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
-#elif defined(__NVCOMPILER)
-#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
-#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
-#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
-  _Pragma("diagnostic push") \
-  _Pragma("diag_suppress deprecated_entity_with_custom_message")
-#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
-#elif defined(_MSC_VER)
-#define BENCHMARK_BUILTIN_EXPECT(x, y) x
-#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
-#define BENCHMARK_WARNING_MSG(msg)                           \
-  __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
-      __LINE__) ") : warning note: " msg))
-#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
-  __pragma(warning(push)) \
-  __pragma(warning(disable : 4996))
-#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
-#else
-#define BENCHMARK_BUILTIN_EXPECT(x, y) x
-#define BENCHMARK_DEPRECATED_MSG(msg)
-#define BENCHMARK_WARNING_MSG(msg)                           \
-  __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
-      __LINE__) ") : warning note: " msg))
-#define BENCHMARK_DISABLE_DEPRECATED_WARNING
-#define BENCHMARK_RESTORE_DEPRECATED_WARNING
-#endif
-// clang-format on
-
-#if defined(__GNUC__) && !defined(__clang__)
-#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
-#endif
-
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
-#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
-#elif defined(_MSC_VER)
-#define BENCHMARK_UNREACHABLE() __assume(false)
-#else
-#define BENCHMARK_UNREACHABLE() ((void)0)
-#endif
-
-#if defined(__GNUC__)
-// Determine the cacheline size based on architecture
-#if defined(__i386__) || defined(__x86_64__)
-#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
-#elif defined(__powerpc64__)
-#define BENCHMARK_INTERNAL_CACHELINE_SIZE 128
-#elif defined(__aarch64__)
-#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
-#elif defined(__arm__)
-// Cache line sizes for ARM: These values are not strictly correct since
-// cache line sizes depend on implementations, not architectures.  There
-// are even implementations with cache line sizes configurable at boot
-// time.
-#if defined(__ARM_ARCH_5T__)
-#define BENCHMARK_INTERNAL_CACHELINE_SIZE 32
-#elif defined(__ARM_ARCH_7A__)
-#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
-#endif  // ARM_ARCH
-#endif  // arches
-#endif  // __GNUC__
-
-#ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE
-// A reasonable default guess.  Note that overestimates tend to waste more
-// space, while underestimates tend to waste more time.
-#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
-#endif
-
-#if defined(__GNUC__)
-// Indicates that the declared object be cache aligned using
-// `BENCHMARK_INTERNAL_CACHELINE_SIZE` (see above).
-#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
-  __attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE)))
-#elif defined(_MSC_VER)
-#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
-  __declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE))
-#else
-#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED
-#endif
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-// C4251: <symbol> needs to have dll-interface to be used by clients of class
-#pragma warning(disable : 4251)
-#endif  // _MSC_VER_
-
-namespace benchmark {
-
-namespace internal {
-#if (__cplusplus < 201402L || (defined(_MSC_VER) && _MSVC_LANG < 201402L))
-template <typename T, typename... Args>
-std::unique_ptr<T> make_unique(Args&&... args) {
-  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
-}
-#else
-using ::std::make_unique;
-#endif
-}  // namespace internal
-
-class BenchmarkReporter;
-class State;
-
-using IterationCount = int64_t;
-
-// Define alias of Setup/Teardown callback function type
-using callback_function = std::function<void(const benchmark::State&)>;
-
-// Default number of minimum benchmark running time in seconds.
-const char kDefaultMinTimeStr[] = "0.5s";
-
-BENCHMARK_EXPORT void MaybeReenterWithoutASLR(int, char**);
-
-// Returns the version of the library.
-BENCHMARK_EXPORT std::string GetBenchmarkVersion();
-
-BENCHMARK_EXPORT void PrintDefaultHelp();
-
-BENCHMARK_EXPORT void Initialize(int* argc, char** argv,
-                                 void (*HelperPrintf)() = PrintDefaultHelp);
-BENCHMARK_EXPORT void Shutdown();
-
-// Report to stdout all arguments in 'argv' as unrecognized except the first.
-// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1).
-BENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);
-
-// Returns the current value of --benchmark_filter.
-BENCHMARK_EXPORT std::string GetBenchmarkFilter();
-
-// Sets a new value to --benchmark_filter. (This will override this flag's
-// current value).
-// Should be called after `benchmark::Initialize()`, as
-// `benchmark::Initialize()` will override the flag's value.
-BENCHMARK_EXPORT void SetBenchmarkFilter(std::string value);
-
-// Returns the current value of --v (command line value for verbosity).
-BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
-
-// Creates a default display reporter. Used by the library when no display
-// reporter is provided, but also made available for external use in case a
-// custom reporter should respect the `--benchmark_format` flag as a fallback
-BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
-
-// Generate a list of benchmarks matching the specified --benchmark_filter flag
-// and if --benchmark_list_tests is specified return after printing the name
-// of each matching benchmark. Otherwise run each matching benchmark and
-// report the results.
-//
-// spec : Specify the benchmarks to run. If users do not specify this arg,
-//        then the value of FLAGS_benchmark_filter
-//        will be used.
-//
-// The second and third overload use the specified 'display_reporter' and
-//  'file_reporter' respectively. 'file_reporter' will write to the file
-//  specified
-//   by '--benchmark_out'. If '--benchmark_out' is not given the
-//  'file_reporter' is ignored.
-//
-// RETURNS: The number of matching benchmarks.
-BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();
-BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);
-
-BENCHMARK_EXPORT size_t
-RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
-BENCHMARK_EXPORT size_t
-RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
-
-BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(
-    BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
-BENCHMARK_EXPORT size_t
-RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
-                       BenchmarkReporter* file_reporter, std::string spec);
-
-// TimeUnit is passed to a benchmark in order to specify the order of magnitude
-// for the measured time.
-enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
-
-BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
-
-// Sets the default time unit the benchmarks use
-// Has to be called before the benchmark loop to take effect
-BENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit);
-
-// If a MemoryManager is registered (via RegisterMemoryManager()),
-// it can be used to collect and report allocation metrics for a run of the
-// benchmark.
-class MemoryManager {
- public:
-  static constexpr int64_t TombstoneValue = std::numeric_limits<int64_t>::max();
-
-  struct Result {
-    Result()
-        : num_allocs(0),
-          max_bytes_used(0),
-          total_allocated_bytes(TombstoneValue),
-          net_heap_growth(TombstoneValue),
-          memory_iterations(0) {}
-
-    // The number of allocations made in total between Start and Stop.
-    int64_t num_allocs;
-
-    // The peak memory use between Start and Stop.
-    int64_t max_bytes_used;
-
-    // The total memory allocated, in bytes, between Start and Stop.
-    // Init'ed to TombstoneValue if metric not available.
-    int64_t total_allocated_bytes;
-
-    // The net changes in memory, in bytes, between Start and Stop.
-    // ie., total_allocated_bytes - total_deallocated_bytes.
-    // Init'ed to TombstoneValue if metric not available.
-    int64_t net_heap_growth;
-
-    IterationCount memory_iterations;
-  };
-
-  virtual ~MemoryManager() {}
-
-  // Implement this to start recording allocation information.
-  virtual void Start() = 0;
-
-  // Implement this to stop recording and fill out the given Result structure.
-  virtual void Stop(Result& result) = 0;
-};
-
-// Register a MemoryManager instance that will be used to collect and report
-// allocation measurements for benchmark runs.
-BENCHMARK_EXPORT
-void RegisterMemoryManager(MemoryManager* memory_manager);
-
-// If a ProfilerManager is registered (via RegisterProfilerManager()), the
-// benchmark will be run an additional time under the profiler to collect and
-// report profile metrics for the run of the benchmark.
-class ProfilerManager {
- public:
-  virtual ~ProfilerManager() {}
-
-  // This is called after `Setup()` code and right before the benchmark is run.
-  virtual void AfterSetupStart() = 0;
-
-  // This is called before `Teardown()` code and right after the benchmark
-  // completes.
-  virtual void BeforeTeardownStop() = 0;
-};
-
-// Register a ProfilerManager instance that will be used to collect and report
-// profile measurements for benchmark runs.
-BENCHMARK_EXPORT
-void RegisterProfilerManager(ProfilerManager* profiler_manager);
-
-// Add a key-value pair to output as part of the context stanza in the report.
-BENCHMARK_EXPORT
-void AddCustomContext(std::string key, std::string value);
-
-class Benchmark;
-
-namespace internal {
-class BenchmarkImp;
-class BenchmarkFamilies;
-
-BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
-
-BENCHMARK_EXPORT
-void UseCharPointer(char const volatile*);
-
-// Take ownership of the pointer and register the benchmark. Return the
-// registered benchmark.
-BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(
-    std::unique_ptr<Benchmark>);
-
-// Ensure that the standard streams are properly initialized in every TU.
-BENCHMARK_EXPORT int InitializeStreams();
-BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
-
-}  // namespace internal
-
-#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
-    defined(__EMSCRIPTEN__)
-#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
-#endif
-
-// Force the compiler to flush pending writes to global memory. Acts as an
-// effective read/write barrier
-inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
-  std::atomic_signal_fence(std::memory_order_acq_rel);
-}
-
-// The DoNotOptimize(...) function can be used to prevent a value or
-// expression from being optimized away by the compiler. This function is
-// intended to add little to no overhead.
-// See: https://youtu.be/nXaxk27zwlk?t=2441
-#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
-#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
-template <class Tp>
-BENCHMARK_DEPRECATED_MSG(
-    "The const-ref version of this method can permit "
-    "undesired compiler optimizations in benchmarks")
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
-  asm volatile("" : : "r,m"(value) : "memory");
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
-#if defined(__clang__)
-  asm volatile("" : "+r,m"(value) : : "memory");
-#else
-  asm volatile("" : "+m,r"(value) : : "memory");
-#endif
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
-#if defined(__clang__)
-  asm volatile("" : "+r,m"(value) : : "memory");
-#else
-  asm volatile("" : "+m,r"(value) : : "memory");
-#endif
-}
-// !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
-#elif (__GNUC__ >= 5)
-// Workaround for a bug with full argument copy overhead with GCC.
-// See: #1340 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105519
-template <class Tp>
-BENCHMARK_DEPRECATED_MSG(
-    "The const-ref version of this method can permit "
-    "undesired compiler optimizations in benchmarks")
-inline BENCHMARK_ALWAYS_INLINE
-    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
-                            (sizeof(Tp) <= sizeof(Tp*))>::type
-    DoNotOptimize(Tp const& value) {
-  asm volatile("" : : "r,m"(value) : "memory");
-}
-
-template <class Tp>
-BENCHMARK_DEPRECATED_MSG(
-    "The const-ref version of this method can permit "
-    "undesired compiler optimizations in benchmarks")
-inline BENCHMARK_ALWAYS_INLINE
-    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
-                            (sizeof(Tp) > sizeof(Tp*))>::type
-    DoNotOptimize(Tp const& value) {
-  asm volatile("" : : "m"(value) : "memory");
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE
-    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
-                            (sizeof(Tp) <= sizeof(Tp*))>::type
-    DoNotOptimize(Tp& value) {
-  asm volatile("" : "+m,r"(value) : : "memory");
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE
-    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
-                            (sizeof(Tp) > sizeof(Tp*))>::type
-    DoNotOptimize(Tp& value) {
-  asm volatile("" : "+m"(value) : : "memory");
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE
-    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
-                            (sizeof(Tp) <= sizeof(Tp*))>::type
-    DoNotOptimize(Tp&& value) {
-  asm volatile("" : "+m,r"(value) : : "memory");
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE
-    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
-                            (sizeof(Tp) > sizeof(Tp*))>::type
-    DoNotOptimize(Tp&& value) {
-  asm volatile("" : "+m"(value) : : "memory");
-}
-// !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
-#endif
-
-#elif defined(_MSC_VER)
-template <class Tp>
-BENCHMARK_DEPRECATED_MSG(
-    "The const-ref version of this method can permit "
-    "undesired compiler optimizations in benchmarks")
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
-  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
-  _ReadWriteBarrier();
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
-  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
-  _ReadWriteBarrier();
-}
-
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
-  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
-  _ReadWriteBarrier();
-}
-#else
-template <class Tp>
-inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
-  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
-}
-// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers, before C++11.
-#endif
-
-// This class is used for user-defined counters.
-class Counter {
- public:
-  enum Flags {
-    kDefaults = 0,
-    // Mark the counter as a rate. It will be presented divided
-    // by the duration of the benchmark.
-    kIsRate = 1 << 0,
-    // Mark the counter as a thread-average quantity. It will be
-    // presented divided by the number of threads.
-    kAvgThreads = 1 << 1,
-    // Mark the counter as a thread-average rate. See above.
-    kAvgThreadsRate = kIsRate | kAvgThreads,
-    // Mark the counter as a constant value, valid/same for *every* iteration.
-    // When reporting, it will be *multiplied* by the iteration count.
-    kIsIterationInvariant = 1 << 2,
-    // Mark the counter as a constant rate.
-    // When reporting, it will be *multiplied* by the iteration count
-    // and then divided by the duration of the benchmark.
-    kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
-    // Mark the counter as a iteration-average quantity.
-    // It will be presented divided by the number of iterations.
-    kAvgIterations = 1 << 3,
-    // Mark the counter as a iteration-average rate. See above.
-    kAvgIterationsRate = kIsRate | kAvgIterations,
-
-    // In the end, invert the result. This is always done last!
-    kInvert = 1 << 31
-  };
-
-  enum OneK {
-    // 1'000 items per 1k
-    kIs1000 = 1000,
-    // 1'024 items per 1k
-    kIs1024 = 1024
-  };
-
-  double value;
-  Flags flags;
-  OneK oneK;
-
-  BENCHMARK_ALWAYS_INLINE
-  Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000)
-      : value(v), flags(f), oneK(k) {}
-
-  BENCHMARK_ALWAYS_INLINE operator double const&() const { return value; }
-  BENCHMARK_ALWAYS_INLINE operator double&() { return value; }
-};
-
-// A helper for user code to create unforeseen combinations of Flags, without
-// having to do this cast manually each time, or providing this operator.
-Counter::Flags inline operator|(const Counter::Flags& LHS,
-                                const Counter::Flags& RHS) {
-  return static_cast<Counter::Flags>(static_cast<int>(LHS) |
-                                     static_cast<int>(RHS));
-}
-
-// This is the container for the user-defined counters.
-typedef std::map<std::string, Counter> UserCounters;
-
-// BigO is passed to a benchmark in order to specify the asymptotic
-// computational
-// complexity for the benchmark. In case oAuto is selected, complexity will be
-// calculated automatically to the best fit.
-enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
-
-typedef int64_t ComplexityN;
-
-enum StatisticUnit { kTime, kPercentage };
-
-// BigOFunc is passed to a benchmark in order to specify the asymptotic
-// computational complexity for the benchmark.
-typedef double(BigOFunc)(ComplexityN);
-
-// StatisticsFunc is passed to a benchmark in order to compute some descriptive
-// statistics over all the measurements of some type
-typedef double(StatisticsFunc)(const std::vector<double>&);
-
-namespace internal {
-struct Statistics {
-  std::string name_;
-  StatisticsFunc* compute_;
-  StatisticUnit unit_;
-
-  Statistics(const std::string& name, StatisticsFunc* compute,
-             StatisticUnit unit = kTime)
-      : name_(name), compute_(compute), unit_(unit) {}
-};
-
-class BenchmarkInstance;
-class ThreadTimer;
-class ThreadManager;
-class PerfCountersMeasurement;
-
-enum AggregationReportMode : unsigned {
-  // The mode has not been manually specified
-  ARM_Unspecified = 0,
-  // The mode is user-specified.
-  // This may or may not be set when the following bit-flags are set.
-  ARM_Default = 1U << 0U,
-  // File reporter should only output aggregates.
-  ARM_FileReportAggregatesOnly = 1U << 1U,
-  // Display reporter should only output aggregates
-  ARM_DisplayReportAggregatesOnly = 1U << 2U,
-  // Both reporters should only display aggregates.
-  ARM_ReportAggregatesOnly =
-      ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
-};
-
-enum Skipped : unsigned {
-  NotSkipped = 0,
-  SkippedWithMessage,
-  SkippedWithError
-};
-
-}  // namespace internal
-
-#if defined(_MSC_VER)
-#pragma warning(push)
-// C4324: 'benchmark::State': structure was padded due to alignment specifier
-#pragma warning(disable : 4324)
-#endif  // _MSC_VER_
-// State is passed to a running Benchmark and contains state for the
-// benchmark to use.
-class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
- public:
-  struct StateIterator;
-  friend struct StateIterator;
-
-  // Returns iterators used to run each iteration of a benchmark using a
-  // C++11 ranged-based for loop. These functions should not be called directly.
-  //
-  // REQUIRES: The benchmark has not started running yet. Neither begin nor end
-  // have been called previously.
-  //
-  // NOTE: KeepRunning may not be used after calling either of these functions.
-  inline BENCHMARK_ALWAYS_INLINE StateIterator begin();
-  inline BENCHMARK_ALWAYS_INLINE StateIterator end();
-
-  // Returns true if the benchmark should continue through another iteration.
-  // NOTE: A benchmark may not return from the test until KeepRunning() has
-  // returned false.
-  inline bool KeepRunning();
-
-  // Returns true iff the benchmark should run n more iterations.
-  // REQUIRES: 'n' > 0.
-  // NOTE: A benchmark must not return from the test until KeepRunningBatch()
-  // has returned false.
-  // NOTE: KeepRunningBatch() may overshoot by up to 'n' iterations.
-  //
-  // Intended usage:
-  //   while (state.KeepRunningBatch(1000)) {
-  //     // process 1000 elements
-  //   }
-  inline bool KeepRunningBatch(IterationCount n);
-
-  // REQUIRES: timer is running and 'SkipWithMessage(...)' or
-  //   'SkipWithError(...)' has not been called by the current thread.
-  // Stop the benchmark timer.  If not called, the timer will be
-  // automatically stopped after the last iteration of the benchmark loop.
-  //
-  // For threaded benchmarks the PauseTiming() function only pauses the timing
-  // for the current thread.
-  //
-  // NOTE: The "real time" measurement is per-thread. If different threads
-  // report different measurements the largest one is reported.
-  //
-  // NOTE: PauseTiming()/ResumeTiming() are relatively
-  // heavyweight, and so their use should generally be avoided
-  // within each benchmark iteration, if possible.
-  void PauseTiming();
-
-  // REQUIRES: timer is not running and 'SkipWithMessage(...)' or
-  //   'SkipWithError(...)' has not been called by the current thread.
-  // Start the benchmark timer.  The timer is NOT running on entrance to the
-  // benchmark function. It begins running after control flow enters the
-  // benchmark loop.
-  //
-  // NOTE: PauseTiming()/ResumeTiming() are relatively
-  // heavyweight, and so their use should generally be avoided
-  // within each benchmark iteration, if possible.
-  void ResumeTiming();
-
-  // REQUIRES: 'SkipWithMessage(...)' or 'SkipWithError(...)' has not been
-  //            called previously by the current thread.
-  // Report the benchmark as resulting in being skipped with the specified
-  // 'msg'.
-  // After this call the user may explicitly 'return' from the benchmark.
-  //
-  // If the ranged-for style of benchmark loop is used, the user must explicitly
-  // break from the loop, otherwise all future iterations will be run.
-  // If the 'KeepRunning()' loop is used the current thread will automatically
-  // exit the loop at the end of the current iteration.
-  //
-  // For threaded benchmarks only the current thread stops executing and future
-  // calls to `KeepRunning()` will block until all threads have completed
-  // the `KeepRunning()` loop. If multiple threads report being skipped only the
-  // first skip message is used.
-  //
-  // NOTE: Calling 'SkipWithMessage(...)' does not cause the benchmark to exit
-  // the current scope immediately. If the function is called from within
-  // the 'KeepRunning()' loop the current iteration will finish. It is the users
-  // responsibility to exit the scope as needed.
-  void SkipWithMessage(const std::string& msg);
-
-  // REQUIRES: 'SkipWithMessage(...)' or 'SkipWithError(...)' has not been
-  //            called previously by the current thread.
-  // Report the benchmark as resulting in an error with the specified 'msg'.
-  // After this call the user may explicitly 'return' from the benchmark.
-  //
-  // If the ranged-for style of benchmark loop is used, the user must explicitly
-  // break from the loop, otherwise all future iterations will be run.
-  // If the 'KeepRunning()' loop is used the current thread will automatically
-  // exit the loop at the end of the current iteration.
-  //
-  // For threaded benchmarks only the current thread stops executing and future
-  // calls to `KeepRunning()` will block until all threads have completed
-  // the `KeepRunning()` loop. If multiple threads report an error only the
-  // first error message is used.
-  //
-  // NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit
-  // the current scope immediately. If the function is called from within
-  // the 'KeepRunning()' loop the current iteration will finish. It is the users
-  // responsibility to exit the scope as needed.
-  void SkipWithError(const std::string& msg);
-
-  // Returns true if 'SkipWithMessage(...)' or 'SkipWithError(...)' was called.
-  bool skipped() const { return internal::NotSkipped != skipped_; }
-
-  // Returns true if an error has been reported with 'SkipWithError(...)'.
-  bool error_occurred() const { return internal::SkippedWithError == skipped_; }
-
-  // REQUIRES: called exactly once per iteration of the benchmarking loop.
-  // Set the manually measured time for this benchmark iteration, which
-  // is used instead of automatically measured time if UseManualTime() was
-  // specified.
-  //
-  // For threaded benchmarks the final value will be set to the largest
-  // reported values.
-  void SetIterationTime(double seconds);
-
-  // Set the number of bytes processed by the current benchmark
-  // execution.  This routine is typically called once at the end of a
-  // throughput oriented benchmark.
-  //
-  // REQUIRES: a benchmark has exited its benchmarking loop.
-  BENCHMARK_ALWAYS_INLINE
-  void SetBytesProcessed(int64_t bytes) {
-    counters["bytes_per_second"] =
-        Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
-  }
-
-  BENCHMARK_ALWAYS_INLINE
-  int64_t bytes_processed() const {
-    if (counters.find("bytes_per_second") != counters.end())
-      return static_cast<int64_t>(counters.at("bytes_per_second"));
-    return 0;
-  }
-
-  // If this routine is called with complexity_n > 0 and complexity report is
-  // requested for the
-  // family benchmark, then current benchmark will be part of the computation
-  // and complexity_n will
-  // represent the length of N.
-  BENCHMARK_ALWAYS_INLINE
-  void SetComplexityN(ComplexityN complexity_n) {
-    complexity_n_ = complexity_n;
-  }
-
-  BENCHMARK_ALWAYS_INLINE
-  ComplexityN complexity_length_n() const { return complexity_n_; }
-
-  // If this routine is called with items > 0, then an items/s
-  // label is printed on the benchmark report line for the currently
-  // executing benchmark. It is typically called at the end of a processing
-  // benchmark where a processing items/second output is desired.
-  //
-  // REQUIRES: a benchmark has exited its benchmarking loop.
-  BENCHMARK_ALWAYS_INLINE
-  void SetItemsProcessed(int64_t items) {
-    counters["items_per_second"] =
-        Counter(static_cast<double>(items), benchmark::Counter::kIsRate);
-  }
-
-  BENCHMARK_ALWAYS_INLINE
-  int64_t items_processed() const {
-    if (counters.find("items_per_second") != counters.end())
-      return static_cast<int64_t>(counters.at("items_per_second"));
-    return 0;
-  }
-
-  // If this routine is called, the specified label is printed at the
-  // end of the benchmark report line for the currently executing
-  // benchmark.  Example:
-  //  static void BM_Compress(benchmark::State& state) {
-  //    ...
-  //    double compress = input_size / output_size;
-  //    state.SetLabel(StrFormat("compress:%.1f%%", 100.0*compression));
-  //  }
-  // Produces output that looks like:
-  //  BM_Compress   50         50   14115038  compress:27.3%
-  //
-  // REQUIRES: a benchmark has exited its benchmarking loop.
-  void SetLabel(const std::string& label);
-
-  // Range arguments for this run. CHECKs if the argument has been set.
-  BENCHMARK_ALWAYS_INLINE
-  int64_t range(std::size_t pos = 0) const {
-    assert(range_.size() > pos);
-    return range_[pos];
-  }
-
-  BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead")
-  int64_t range_x() const { return range(0); }
-
-  BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead")
-  int64_t range_y() const { return range(1); }
-
-  // Number of threads concurrently executing the benchmark.
-  BENCHMARK_ALWAYS_INLINE
-  int threads() const { return threads_; }
-
-  // Index of the executing thread. Values from [0, threads).
-  BENCHMARK_ALWAYS_INLINE
-  int thread_index() const { return thread_index_; }
-
-  BENCHMARK_ALWAYS_INLINE
-  IterationCount iterations() const {
-    if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
-      return 0;
-    }
-    return max_iterations - total_iterations_ + batch_leftover_;
-  }
-
-  BENCHMARK_ALWAYS_INLINE
-  std::string name() const { return name_; }
-
-  size_t range_size() const { return range_.size(); }
-
- private:
-  // items we expect on the first cache line (ie 64 bytes of the struct)
-  // When total_iterations_ is 0, KeepRunning() and friends will return false.
-  // May be larger than max_iterations.
-  IterationCount total_iterations_;
-
-  // When using KeepRunningBatch(), batch_leftover_ holds the number of
-  // iterations beyond max_iters that were run. Used to track
-  // completed_iterations_ accurately.
-  IterationCount batch_leftover_;
-
- public:
-  const IterationCount max_iterations;
-
- private:
-  bool started_;
-  bool finished_;
-  internal::Skipped skipped_;
-
-  // items we don't need on the first cache line
-  std::vector<int64_t> range_;
-
-  ComplexityN complexity_n_;
-
- public:
-  // Container for user-defined counters.
-  UserCounters counters;
-
- private:
-  State(std::string name, IterationCount max_iters,
-        const std::vector<int64_t>& ranges, int thread_i, int n_threads,
-        internal::ThreadTimer* timer, internal::ThreadManager* manager,
-        internal::PerfCountersMeasurement* perf_counters_measurement,
-        ProfilerManager* profiler_manager);
-
-  void StartKeepRunning();
-  // Implementation of KeepRunning() and KeepRunningBatch().
-  // is_batch must be true unless n is 1.
-  inline bool KeepRunningInternal(IterationCount n, bool is_batch);
-  void FinishKeepRunning();
-
-  const std::string name_;
-  const int thread_index_;
-  const int threads_;
-
-  internal::ThreadTimer* const timer_;
-  internal::ThreadManager* const manager_;
-  internal::PerfCountersMeasurement* const perf_counters_measurement_;
-  ProfilerManager* const profiler_manager_;
-
-  friend class internal::BenchmarkInstance;
-};
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif  // _MSC_VER_
-
-inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() {
-  return KeepRunningInternal(1, /*is_batch=*/false);
-}
-
-inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningBatch(IterationCount n) {
-  return KeepRunningInternal(n, /*is_batch=*/true);
-}
-
-inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningInternal(IterationCount n,
-                                                               bool is_batch) {
-  // total_iterations_ is set to 0 by the constructor, and always set to a
-  // nonzero value by StartKepRunning().
-  assert(n > 0);
-  // n must be 1 unless is_batch is true.
-  assert(is_batch || n == 1);
-  if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {
-    total_iterations_ -= n;
-    return true;
-  }
-  if (!started_) {
-    StartKeepRunning();
-    if (!skipped() && total_iterations_ >= n) {
-      total_iterations_ -= n;
-      return true;
-    }
-  }
-  // For non-batch runs, total_iterations_ must be 0 by now.
-  if (is_batch && total_iterations_ != 0) {
-    batch_leftover_ = n - total_iterations_;
-    total_iterations_ = 0;
-    return true;
-  }
-  FinishKeepRunning();
-  return false;
-}
-
-struct State::StateIterator {
-  struct BENCHMARK_UNUSED Value {};
-  typedef std::forward_iterator_tag iterator_category;
-  typedef Value value_type;
-  typedef Value reference;
-  typedef Value pointer;
-  typedef std::ptrdiff_t difference_type;
-
- private:
-  friend class State;
-  BENCHMARK_ALWAYS_INLINE
-  StateIterator() : cached_(0), parent_() {}
-
-  BENCHMARK_ALWAYS_INLINE
-  explicit StateIterator(State* st)
-      : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
-
- public:
-  BENCHMARK_ALWAYS_INLINE
-  Value operator*() const { return Value(); }
-
-  BENCHMARK_ALWAYS_INLINE
-  StateIterator& operator++() {
-    assert(cached_ > 0);
-    --cached_;
-    return *this;
-  }
-
-  BENCHMARK_ALWAYS_INLINE
-  bool operator!=(StateIterator const&) const {
-    if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0, true)) return true;
-    parent_->FinishKeepRunning();
-    return false;
-  }
-
- private:
-  IterationCount cached_;
-  State* const parent_;
-};
-
-inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
-  return StateIterator(this);
-}
-inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
-  StartKeepRunning();
-  return StateIterator();
-}
-
-// Base class for user-defined multi-threading
-struct ThreadRunnerBase {
-  virtual ~ThreadRunnerBase() {}
-  virtual void RunThreads(const std::function<void(int)>& fn) = 0;
-};
-
-// Define alias of ThreadRunner factory function type
-using threadrunner_factory =
-    std::function<std::unique_ptr<ThreadRunnerBase>(int)>;
-
-// ------------------------------------------------------
-// Benchmark registration object.  The BENCHMARK() macro expands into a
-// Benchmark* object.  Various methods can be called on this object to
-// change the properties of the benchmark.  Each method returns "this" so
-// that multiple method calls can chained into one expression.
-class BENCHMARK_EXPORT Benchmark {
- public:
-  virtual ~Benchmark();
-
-  // Note: the following methods all return "this" so that multiple
-  // method calls can be chained together in one expression.
-
-  // Specify the name of the benchmark
-  Benchmark* Name(const std::string& name);
-
-  // Run this benchmark once with "x" as the extra argument passed
-  // to the function.
-  // REQUIRES: The function passed to the constructor must accept an arg1.
-  Benchmark* Arg(int64_t x);
-
-  // Run this benchmark with the given time unit for the generated output report
-  Benchmark* Unit(TimeUnit unit);
-
-  // Run this benchmark once for a number of values picked from the
-  // range [start..limit].  (start and limit are always picked.)
-  // REQUIRES: The function passed to the constructor must accept an arg1.
-  Benchmark* Range(int64_t start, int64_t limit);
-
-  // Run this benchmark once for all values in the range [start..limit] with
-  // specific step
-  // REQUIRES: The function passed to the constructor must accept an arg1.
-  Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);
-
-  // Run this benchmark once with "args" as the extra arguments passed
-  // to the function.
-  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
-  Benchmark* Args(const std::vector<int64_t>& args);
-
-  // Equivalent to Args({x, y})
-  // NOTE: This is a legacy C++03 interface provided for compatibility only.
-  //   New code should use 'Args'.
-  Benchmark* ArgPair(int64_t x, int64_t y) {
-    std::vector<int64_t> args;
-    args.push_back(x);
-    args.push_back(y);
-    return Args(args);
-  }
-
-  // Run this benchmark once for a number of values picked from the
-  // ranges [start..limit].  (starts and limits are always picked.)
-  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
-  Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t>>& ranges);
-
-  // Run this benchmark once for each combination of values in the (cartesian)
-  // product of the supplied argument lists.
-  // REQUIRES: The function passed to the constructor must accept arg1, arg2 ...
-  Benchmark* ArgsProduct(const std::vector<std::vector<int64_t>>& arglists);
-
-  // Equivalent to ArgNames({name})
-  Benchmark* ArgName(const std::string& name);
-
-  // Set the argument names to display in the benchmark name. If not called,
-  // only argument values will be shown.
-  Benchmark* ArgNames(const std::vector<std::string>& names);
-
-  // Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}).
-  // NOTE: This is a legacy C++03 interface provided for compatibility only.
-  //   New code should use 'Ranges'.
-  Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
-    std::vector<std::pair<int64_t, int64_t>> ranges;
-    ranges.push_back(std::make_pair(lo1, hi1));
-    ranges.push_back(std::make_pair(lo2, hi2));
-    return Ranges(ranges);
-  }
-
-  // Have "setup" and/or "teardown" invoked once for every benchmark run.
-  // If the benchmark is multi-threaded (will run in k threads concurrently),
-  // the setup callback will be be invoked exactly once (not k times) before
-  // each run with k threads. Time allowing (e.g. for a short benchmark), there
-  // may be multiple such runs per benchmark, each run with its own
-  // "setup"/"teardown".
-  //
-  // If the benchmark uses different size groups of threads (e.g. via
-  // ThreadRange), the above will be true for each size group.
-  //
-  // The callback will be passed a State object, which includes the number
-  // of threads, thread-index, benchmark arguments, etc.
-  Benchmark* Setup(callback_function&&);
-  Benchmark* Setup(const callback_function&);
-  Benchmark* Teardown(callback_function&&);
-  Benchmark* Teardown(const callback_function&);
-
-  // Pass this benchmark object to *func, which can customize
-  // the benchmark by calling various methods like Arg, Args,
-  // Threads, etc.
-  Benchmark* Apply(const std::function<void(Benchmark* benchmark)>&);
-
-  // Set the range multiplier for non-dense range. If not called, the range
-  // multiplier kRangeMultiplier will be used.
-  Benchmark* RangeMultiplier(int multiplier);
-
-  // Set the minimum amount of time to use when running this benchmark. This
-  // option overrides the `benchmark_min_time` flag.
-  // REQUIRES: `t > 0` and `Iterations` has not been called on this benchmark.
-  Benchmark* MinTime(double t);
-
-  // Set the minimum amount of time to run the benchmark before taking runtimes
-  // of this benchmark into account. This
-  // option overrides the `benchmark_min_warmup_time` flag.
-  // REQUIRES: `t >= 0` and `Iterations` has not been called on this benchmark.
-  Benchmark* MinWarmUpTime(double t);
-
-  // Specify the amount of iterations that should be run by this benchmark.
-  // This option overrides the `benchmark_min_time` flag.
-  // REQUIRES: 'n > 0' and `MinTime` has not been called on this benchmark.
-  //
-  // NOTE: This function should only be used when *exact* iteration control is
-  //   needed and never to control or limit how long a benchmark runs, where
-  // `--benchmark_min_time=<N>s` or `MinTime(...)` should be used instead.
-  Benchmark* Iterations(IterationCount n);
-
-  // Specify the amount of times to repeat this benchmark. This option overrides
-  // the `benchmark_repetitions` flag.
-  // REQUIRES: `n > 0`
-  Benchmark* Repetitions(int n);
-
-  // Specify if each repetition of the benchmark should be reported separately
-  // or if only the final statistics should be reported. If the benchmark
-  // is not repeated then the single result is always reported.
-  // Applies to *ALL* reporters (display and file).
-  Benchmark* ReportAggregatesOnly(bool value = true);
-
-  // Same as ReportAggregatesOnly(), but applies to display reporter only.
-  Benchmark* DisplayAggregatesOnly(bool value = true);
-
-  // By default, the CPU time is measured only for the main thread, which may
-  // be unrepresentative if the benchmark uses threads internally. If called,
-  // the total CPU time spent by all the threads will be measured instead.
-  // By default, only the main thread CPU time will be measured.
-  Benchmark* MeasureProcessCPUTime();
-
-  // If a particular benchmark should use the Wall clock instead of the CPU time
-  // (be it either the CPU time of the main thread only (default), or the
-  // total CPU usage of the benchmark), call this method. If called, the elapsed
-  // (wall) time will be used to control how many iterations are run, and in the
-  // printing of items/second or MB/seconds values.
-  // If not called, the CPU time used by the benchmark will be used.
-  Benchmark* UseRealTime();
-
-  // If a benchmark must measure time manually (e.g. if GPU execution time is
-  // being
-  // measured), call this method. If called, each benchmark iteration should
-  // call
-  // SetIterationTime(seconds) to report the measured time, which will be used
-  // to control how many iterations are run, and in the printing of items/second
-  // or MB/second values.
-  Benchmark* UseManualTime();
-
-  // Set the asymptotic computational complexity for the benchmark. If called
-  // the asymptotic computational complexity will be shown on the output.
-  Benchmark* Complexity(BigO complexity = benchmark::oAuto);
-
-  // Set the asymptotic computational complexity for the benchmark. If called
-  // the asymptotic computational complexity will be shown on the output.
-  Benchmark* Complexity(BigOFunc* complexity);
-
-  // Add this statistics to be computed over all the values of benchmark run
-  Benchmark* ComputeStatistics(const std::string& name,
-                               StatisticsFunc* statistics,
-                               StatisticUnit unit = kTime);
-
-  // Support for running multiple copies of the same benchmark concurrently
-  // in multiple threads.  This may be useful when measuring the scaling
-  // of some piece of code.
-
-  // Run one instance of this benchmark concurrently in t threads.
-  Benchmark* Threads(int t);
-
-  // Pick a set of values T from [min_threads,max_threads].
-  // min_threads and max_threads are always included in T.  Run this
-  // benchmark once for each value in T.  The benchmark run for a
-  // particular value t consists of t threads running the benchmark
-  // function concurrently.  For example, consider:
-  //    BENCHMARK(Foo)->ThreadRange(1,16);
-  // This will run the following benchmarks:
-  //    Foo in 1 thread
-  //    Foo in 2 threads
-  //    Foo in 4 threads
-  //    Foo in 8 threads
-  //    Foo in 16 threads
-  Benchmark* ThreadRange(int min_threads, int max_threads);
-
-  // For each value n in the range, run this benchmark once using n threads.
-  // min_threads and max_threads are always included in the range.
-  // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts
-  // a benchmark with 1, 4, 7 and 8 threads.
-  Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1);
-
-  // Equivalent to ThreadRange(NumCPUs(), NumCPUs())
-  Benchmark* ThreadPerCpu();
-
-  // Sets a user-defined threadrunner (see ThreadRunnerBase)
-  Benchmark* ThreadRunner(threadrunner_factory&& factory);
-
-  virtual void Run(State& state) = 0;
-
-  TimeUnit GetTimeUnit() const;
-
- protected:
-  explicit Benchmark(const std::string& name);
-  void SetName(const std::string& name);
-
- public:
-  const char* GetName() const;
-  int ArgsCnt() const;
-  const char* GetArgName(int arg) const;
-
- private:
-  friend class internal::BenchmarkFamilies;
-  friend class internal::BenchmarkInstance;
-
-  std::string name_;
-  internal::AggregationReportMode aggregation_report_mode_;
-  std::vector<std::string> arg_names_;      // Args for all benchmark runs
-  std::vector<std::vector<int64_t>> args_;  // Args for all benchmark runs
-
-  TimeUnit time_unit_;
-  bool use_default_time_unit_;
-
-  int range_multiplier_;
-  double min_time_;
-  double min_warmup_time_;
-  IterationCount iterations_;
-  int repetitions_;
-  bool measure_process_cpu_time_;
-  bool use_real_time_;
-  bool use_manual_time_;
-  BigO complexity_;
-  BigOFunc* complexity_lambda_;
-  std::vector<internal::Statistics> statistics_;
-  std::vector<int> thread_counts_;
-
-  callback_function setup_;
-  callback_function teardown_;
-
-  threadrunner_factory threadrunner_;
-
-  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
-};
-
-namespace internal {
-
-// clang-format off
-typedef BENCHMARK_DEPRECATED_MSG("Use ::benchmark::Benchmark instead")
-    ::benchmark::Benchmark Benchmark;
-typedef BENCHMARK_DEPRECATED_MSG(
-    "Use ::benchmark::threadrunner_factory instead")
-    ::benchmark::threadrunner_factory threadrunner_factory;
-// clang-format on
-
-typedef void(Function)(State&);
-
-}  // namespace internal
-
-// Create and register a benchmark with the specified 'name' that invokes
-// the specified functor 'fn'.
-//
-// RETURNS: A pointer to the registered benchmark.
-Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn);
-
-template <class Lambda>
-Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
-
-// Remove all registered benchmarks. All pointers to previously registered
-// benchmarks are invalidated.
-BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
-
-namespace internal {
-// The class used to hold all Benchmarks created from static function.
-// (ie those created using the BENCHMARK(...) macros.
-class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark {
- public:
-  FunctionBenchmark(const std::string& name, Function* func)
-      : Benchmark(name), func_(func) {}
-
-  void Run(State& st) override;
-
- private:
-  Function* func_;
-};
-
-template <class Lambda>
-class LambdaBenchmark : public benchmark::Benchmark {
- public:
-  void Run(State& st) override { lambda_(st); }
-
-  template <class OLambda>
-  LambdaBenchmark(const std::string& name, OLambda&& lam)
-      : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
-
- private:
-  LambdaBenchmark(LambdaBenchmark const&) = delete;
-  Lambda lambda_;
-};
-}  // namespace internal
-
-inline Benchmark* RegisterBenchmark(const std::string& name,
-                                    internal::Function* fn) {
-  return internal::RegisterBenchmarkInternal(
-      ::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
-                                                                      fn));
-}
-
-template <class Lambda>
-Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
-  using BenchType =
-      internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
-  return internal::RegisterBenchmarkInternal(
-      ::benchmark::internal::make_unique<BenchType>(name,
-                                                    std::forward<Lambda>(fn)));
-}
-
-template <class Lambda, class... Args>
-Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
-                             Args&&... args) {
-  return benchmark::RegisterBenchmark(
-      name, [=](benchmark::State& st) { fn(st, args...); });
-}
-
-// The base class for all fixture tests.
-class Fixture : public Benchmark {
- public:
-  Fixture() : Benchmark("") {}
-
-  void Run(State& st) override {
-    this->SetUp(st);
-    this->BenchmarkCase(st);
-    this->TearDown(st);
-  }
-
-  // These will be deprecated ...
-  virtual void SetUp(const State&) {}
-  virtual void TearDown(const State&) {}
-  // ... In favor of these.
-  virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); }
-  virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); }
-
- protected:
-  virtual void BenchmarkCase(State&) = 0;
-};
-}  // namespace benchmark
-
-// ------------------------------------------------------
-// Macro to register benchmarks
-
-// clang-format off
-#if defined(__clang__)
-#define BENCHMARK_DISABLE_COUNTER_WARNING                        \
-  _Pragma("GCC diagnostic push")                                 \
-  _Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \
-  _Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"")
-#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop")
-#else
-#define BENCHMARK_DISABLE_COUNTER_WARNING
-#define BENCHMARK_RESTORE_COUNTER_WARNING
-#endif
-// clang-format on
-
-// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
-// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
-// empty. If X is empty the expression becomes (+1 == +0).
-BENCHMARK_DISABLE_COUNTER_WARNING
-#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
-#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
-#else
-#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
-#endif
-BENCHMARK_RESTORE_COUNTER_WARNING
-
-// Helpers for generating unique variable names
-#define BENCHMARK_PRIVATE_NAME(...)                                      \
-  BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
-                           __VA_ARGS__)
-
-#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
-#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
-// Helper for concatenation with macro name expansion
-#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
-  BaseClass##_##Method##_Benchmark
-
-#define BENCHMARK_PRIVATE_DECLARE(n)                                   \
-  BENCHMARK_DISABLE_COUNTER_WARNING                                    \
-  /* NOLINTNEXTLINE(misc-use-anonymous-namespace) */                   \
-  static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \
-      BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED
-
-#define BENCHMARK(...)                                   \
-  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \
-      (::benchmark::internal::RegisterBenchmarkInternal( \
-          ::benchmark::internal::make_unique<            \
-              ::benchmark::internal::FunctionBenchmark>( \
-              #__VA_ARGS__,                              \
-              static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
-
-// Old-style macros
-#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
-#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
-#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
-#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
-#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
-  BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
-
-// Register a benchmark which invokes the function specified by `func`
-// with the additional arguments specified by `...`.
-//
-// For example:
-//
-// template <class ...ExtraArgs>`
-// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {
-//  [...]
-//}
-// /* Registers a benchmark named "BM_takes_args/int_string_test` */
-// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc"));
-#define BENCHMARK_CAPTURE(func, test_case_name, ...)     \
-  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \
-      (::benchmark::internal::RegisterBenchmarkInternal( \
-          ::benchmark::internal::make_unique<            \
-              ::benchmark::internal::FunctionBenchmark>( \
-              #func "/" #test_case_name,                 \
-              [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
-
-// Register a benchmark named `func/test_case_name` which invokes `func`
-// directly (no lambda, no extra arguments). Use this instead of
-// BENCHMARK_CAPTURE when you only need a custom name and do not need to
-// pass additional arguments. This avoids the lambda overhead that causes
-// compiler and linker scalability issues when registering large numbers of
-// benchmarks.
-//
-// For example:
-//
-// void BM_Foo(benchmark::State& state) {
-//   for (auto _ : state) {}
-// }
-// /* Registers a benchmark named "BM_Foo/my_variant" */
-// BENCHMARK_NAMED(BM_Foo, my_variant);
-#define BENCHMARK_NAMED(func, test_case_name)            \
-  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \
-      (::benchmark::internal::RegisterBenchmarkInternal( \
-          ::benchmark::internal::make_unique<            \
-              ::benchmark::internal::FunctionBenchmark>( \
-              #func "/" #test_case_name,                 \
-              static_cast<::benchmark::internal::Function*>(func))))
-
-// This will register a benchmark for a templatized function.  For example:
-//
-// template<int arg>
-// void BM_Foo(int iters);
-//
-// BENCHMARK_TEMPLATE(BM_Foo, 1);
-//
-// will register BM_Foo<1> as a benchmark.
-#define BENCHMARK_TEMPLATE1(n, a)                        \
-  BENCHMARK_PRIVATE_DECLARE(n) =                         \
-      (::benchmark::internal::RegisterBenchmarkInternal( \
-          ::benchmark::internal::make_unique<            \
-              ::benchmark::internal::FunctionBenchmark>( \
-              #n "<" #a ">",                             \
-              static_cast<::benchmark::internal::Function*>(n<a>))))
-
-#define BENCHMARK_TEMPLATE2(n, a, b)                     \
-  BENCHMARK_PRIVATE_DECLARE(n) =                         \
-      (::benchmark::internal::RegisterBenchmarkInternal( \
-          ::benchmark::internal::make_unique<            \
-              ::benchmark::internal::FunctionBenchmark>( \
-              #n "<" #a "," #b ">",                      \
-              static_cast<::benchmark::internal::Function*>(n<a, b>))))
-
-#define BENCHMARK_TEMPLATE(n, ...)                       \
-  BENCHMARK_PRIVATE_DECLARE(n) =                         \
-      (::benchmark::internal::RegisterBenchmarkInternal( \
-          ::benchmark::internal::make_unique<            \
-              ::benchmark::internal::FunctionBenchmark>( \
-              #n "<" #__VA_ARGS__ ">",                   \
-              static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
-
-// This will register a benchmark for a templatized function,
-// with the additional arguments specified by `...`.
-//
-// For example:
-//
-// template <typename T, class ...ExtraArgs>`
-// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {
-//  [...]
-//}
-// /* Registers a benchmark named "BM_takes_args<void>/int_string_test` */
-// BENCHMARK_TEMPLATE1_CAPTURE(BM_takes_args, void, int_string_test, 42,
-//                             std::string("abc"));
-#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
-  BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
-
-#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
-  BENCHMARK_PRIVATE_DECLARE(func) =                                  \
-      (::benchmark::internal::RegisterBenchmarkInternal(             \
-          ::benchmark::internal::make_unique<                        \
-              ::benchmark::internal::FunctionBenchmark>(             \
-              #func "<" #a "," #b ">"                                \
-                    "/" #test_case_name,                             \
-              [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
-
-#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method)        \
-  class BaseClass##_##Method##_Benchmark : public BaseClass { \
-   public:                                                    \
-    BaseClass##_##Method##_Benchmark() {                      \
-      this->SetName(#BaseClass "/" #Method);                  \
-    }                                                         \
-                                                              \
-   protected:                                                 \
-    void BenchmarkCase(::benchmark::State&) override;         \
-  };
-
-#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
-  class BaseClass##_##Method##_Benchmark : public BaseClass<a> {    \
-   public:                                                          \
-    BaseClass##_##Method##_Benchmark() {                            \
-      this->SetName(#BaseClass "<" #a ">/" #Method);                \
-    }                                                               \
-                                                                    \
-   protected:                                                       \
-    void BenchmarkCase(::benchmark::State&) override;               \
-  };
-
-#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
-  class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> {    \
-   public:                                                             \
-    BaseClass##_##Method##_Benchmark() {                               \
-      this->SetName(#BaseClass "<" #a "," #b ">/" #Method);            \
-    }                                                                  \
-                                                                       \
-   protected:                                                          \
-    void BenchmarkCase(::benchmark::State&) override;                  \
-  };
-
-#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...)       \
-  class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
-   public:                                                                 \
-    BaseClass##_##Method##_Benchmark() {                                   \
-      this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method);             \
-    }                                                                      \
-                                                                           \
-   protected:                                                              \
-    void BenchmarkCase(::benchmark::State&) override;                      \
-  };
-
-#define BENCHMARK_DEFINE_F(BaseClass, Method)    \
-  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)    \
-  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b)    \
-  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...)            \
-  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-#define BENCHMARK_REGISTER_F(BaseClass, Method) \
-  BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
-
-#define BENCHMARK_PRIVATE_REGISTER_F(TestName)           \
-  BENCHMARK_PRIVATE_DECLARE(TestName) =                  \
-      (::benchmark::internal::RegisterBenchmarkInternal( \
-          ::benchmark::internal::make_unique<TestName>()))
-
-#define BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
-  BaseClass##_##Method##_BenchmarkTemplate
-
-#define BENCHMARK_TEMPLATE_METHOD_F(BaseClass, Method)              \
-  template <class... Args>                                          \
-  class BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
-      : public BaseClass<Args...> {                                 \
-   protected:                                                       \
-    using Base = BaseClass<Args...>;                                \
-    void BenchmarkCase(::benchmark::State&) override;               \
-  };                                                                \
-  template <class... Args>                                          \
-  void BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(                    \
-      BaseClass, Method)<Args...>::BenchmarkCase
-
-#define BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(BaseClass, Method,           \
-                                                 UniqueName, ...)             \
-  class UniqueName : public BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(         \
-                         BaseClass, Method)<__VA_ARGS__> {                    \
-   public:                                                                    \
-    UniqueName() { this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); } \
-  };                                                                          \
-  BENCHMARK_PRIVATE_DECLARE(BaseClass##_##Method##_Benchmark) =               \
-      (::benchmark::internal::RegisterBenchmarkInternal(                      \
-          ::benchmark::internal::make_unique<UniqueName>()))
-
-#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...)    \
-  BENCHMARK_DISABLE_COUNTER_WARNING                                 \
-  BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(                         \
-      BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
-      __VA_ARGS__)                                                  \
-  BENCHMARK_RESTORE_COUNTER_WARNING
-
-// This macro will define and register a benchmark within a fixture class.
-#define BENCHMARK_F(BaseClass, Method)           \
-  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
-  BENCHMARK_REGISTER_F(BaseClass, Method);       \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)           \
-  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
-  BENCHMARK_REGISTER_F(BaseClass, Method);                    \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b)           \
-  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
-  BENCHMARK_REGISTER_F(BaseClass, Method);                       \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...)                   \
-  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
-  BENCHMARK_REGISTER_F(BaseClass, Method);                             \
-  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
-
-// Helper macro to create a main routine in a test that runs the benchmarks
-// Note the workaround for Hexagon simulator passing argc != 0, argv = NULL.
-#define BENCHMARK_MAIN()                                                \
-  int main(int argc, char** argv) {                                     \
-    benchmark::MaybeReenterWithoutASLR(argc, argv);                     \
-    char arg0_default[] = "benchmark";                                  \
-    char* args_default = reinterpret_cast<char*>(arg0_default);         \
-    if (!argv) {                                                        \
-      argc = 1;                                                         \
-      argv = &args_default;                                             \
-    }                                                                   \
-    ::benchmark::Initialize(&argc, argv);                               \
-    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
-    ::benchmark::RunSpecifiedBenchmarks();                              \
-    ::benchmark::Shutdown();                                            \
-    return 0;                                                           \
-  }                                                                     \
-  int main(int, char**)
-
-// ------------------------------------------------------
-// Benchmark Reporters
-
-namespace benchmark {
-
-struct BENCHMARK_EXPORT CPUInfo {
-  struct CacheInfo {
-    std::string type;
-    int level;
-    int size;
-    int num_sharing;
-  };
-
-  enum Scaling { UNKNOWN, ENABLED, DISABLED };
-
-  int num_cpus;
-  Scaling scaling;
-  double cycles_per_second;
-  std::vector<CacheInfo> caches;
-  std::vector<double> load_avg;
-
-  static const CPUInfo& Get();
-
- private:
-  CPUInfo();
-  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo);
-};
-
-// Adding Struct for System Information
-struct BENCHMARK_EXPORT SystemInfo {
-  enum class ASLR { UNKNOWN, ENABLED, DISABLED };
-
-  std::string name;
-  ASLR ASLRStatus;
-  static const SystemInfo& Get();
-
- private:
-  SystemInfo();
-  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);
-};
-
-// BenchmarkName contains the components of the Benchmark's name
-// which allows individual fields to be modified or cleared before
-// building the final name using 'str()'.
-struct BENCHMARK_EXPORT BenchmarkName {
-  std::string function_name;
-  std::string args;
-  std::string min_time;
-  std::string min_warmup_time;
-  std::string iterations;
-  std::string repetitions;
-  std::string time_type;
-  std::string threads;
-
-  // Return the full name of the benchmark with each non-empty
-  // field separated by a '/'
-  std::string str() const;
-};
-
-// Interface for custom benchmark result printers.
-// By default, benchmark reports are printed to stdout. However an application
-// can control the destination of the reports by calling
-// RunSpecifiedBenchmarks and passing it a custom reporter object.
-// The reporter object must implement the following interface.
-class BENCHMARK_EXPORT BenchmarkReporter {
- public:
-  struct Context {
-    CPUInfo const& cpu_info;
-    SystemInfo const& sys_info;
-    // The number of chars in the longest benchmark name.
-    size_t name_field_width = 0;
-    static const char* executable_name;
-    Context();
-  };
-
-  struct BENCHMARK_EXPORT Run {
-    static const int64_t no_repetition_index = -1;
-    enum RunType { RT_Iteration, RT_Aggregate };
-
-    Run()
-        : run_type(RT_Iteration),
-          aggregate_unit(kTime),
-          skipped(internal::NotSkipped),
-          iterations(1),
-          threads(1),
-          time_unit(GetDefaultTimeUnit()),
-          real_accumulated_time(0),
-          cpu_accumulated_time(0),
-          max_heapbytes_used(0),
-          use_real_time_for_initial_big_o(false),
-          complexity(oNone),
-          complexity_lambda(),
-          complexity_n(0),
-          statistics(),
-          report_big_o(false),
-          report_rms(false),
-          allocs_per_iter(0.0) {}
-
-    std::string benchmark_name() const;
-    BenchmarkName run_name;
-    int64_t family_index;
-    int64_t per_family_instance_index;
-    RunType run_type;
-    std::string aggregate_name;
-    StatisticUnit aggregate_unit;
-    std::string report_label;  // Empty if not set by benchmark.
-    internal::Skipped skipped;
-    std::string skip_message;
-
-    IterationCount iterations;
-    int64_t threads;
-    int64_t repetition_index;
-    int64_t repetitions;
-    TimeUnit time_unit;
-    double real_accumulated_time;
-    double cpu_accumulated_time;
-
-    // Return a value representing the real time per iteration in the unit
-    // specified by 'time_unit'.
-    // NOTE: If 'iterations' is zero the returned value represents the
-    // accumulated time.
-    double GetAdjustedRealTime() const;
-
-    // Return a value representing the cpu time per iteration in the unit
-    // specified by 'time_unit'.
-    // NOTE: If 'iterations' is zero the returned value represents the
-    // accumulated time.
-    double GetAdjustedCPUTime() const;
-
-    // This is set to 0.0 if memory tracing is not enabled.
-    double max_heapbytes_used;
-
-    // By default Big-O is computed for CPU time, but that is not what you want
-    // to happen when manual time was requested, which is stored as real time.
-    bool use_real_time_for_initial_big_o;
-
-    // Keep track of arguments to compute asymptotic complexity
-    BigO complexity;
-    BigOFunc* complexity_lambda;
-    ComplexityN complexity_n;
-
-    // what statistics to compute from the measurements
-    const std::vector<internal::Statistics>* statistics;
-
-    // Inform print function whether the current run is a complexity report
-    bool report_big_o;
-    bool report_rms;
-
-    UserCounters counters;
-
-    // Memory metrics.
-    MemoryManager::Result memory_result;
-    double allocs_per_iter;
-  };
-
-  struct PerFamilyRunReports {
-    PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}
-
-    // How many runs will all instances of this benchmark perform?
-    int num_runs_total;
-
-    // How many runs have happened already?
-    int num_runs_done;
-
-    // The reports about (non-errneous!) runs of this family.
-    std::vector<BenchmarkReporter::Run> Runs;
-  };
-
-  // Construct a BenchmarkReporter with the output stream set to 'std::cout'
-  // and the error stream set to 'std::cerr'
-  BenchmarkReporter();
-
-  // Called once for every suite of benchmarks run.
-  // The parameter "context" contains information that the
-  // reporter may wish to use when generating its report, for example the
-  // platform under which the benchmarks are running. The benchmark run is
-  // never started if this function returns false, allowing the reporter
-  // to skip runs based on the context information.
-  virtual bool ReportContext(const Context& context) = 0;
-
-  // Called once for each group of benchmark runs, gives information about
-  // the configurations of the runs.
-  virtual void ReportRunsConfig(double /*min_time*/,
-                                bool /*has_explicit_iters*/,
-                                IterationCount /*iters*/) {}
-
-  // Called once for each group of benchmark runs, gives information about
-  // cpu-time and heap memory usage during the benchmark run. If the group
-  // of runs contained more than two entries then 'report' contains additional
-  // elements representing the mean and standard deviation of those runs.
-  // Additionally if this group of runs was the last in a family of benchmarks
-  // 'reports' contains additional entries representing the asymptotic
-  // complexity and RMS of that benchmark family.
-  virtual void ReportRuns(const std::vector<Run>& report) = 0;
-
-  // Called once and only once after ever group of benchmarks is run and
-  // reported.
-  virtual void Finalize() {}
-
-  // REQUIRES: The object referenced by 'out' is valid for the lifetime
-  // of the reporter.
-  void SetOutputStream(std::ostream* out) {
-    assert(out);
-    output_stream_ = out;
-  }
-
-  // REQUIRES: The object referenced by 'err' is valid for the lifetime
-  // of the reporter.
-  void SetErrorStream(std::ostream* err) {
-    assert(err);
-    error_stream_ = err;
-  }
-
-  std::ostream& GetOutputStream() const { return *output_stream_; }
-
-  std::ostream& GetErrorStream() const { return *error_stream_; }
-
-  virtual ~BenchmarkReporter();
-
-  // Write a human readable string to 'out' representing the specified
-  // 'context'.
-  // REQUIRES: 'out' is non-null.
-  static void PrintBasicContext(std::ostream* out, Context const& context);
-
- private:
-  std::ostream* output_stream_;
-  std::ostream* error_stream_;
-};
-
-// Simple reporter that outputs benchmark data to the console. This is the
-// default reporter used by RunSpecifiedBenchmarks().
-class BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter {
- public:
-  enum OutputOptions {
-    OO_None = 0,
-    OO_Color = 1,
-    OO_Tabular = 2,
-    OO_ColorTabular = OO_Color | OO_Tabular,
-    OO_Defaults = OO_ColorTabular
-  };
-  explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)
-      : output_options_(opts_), name_field_width_(0), printed_header_(false) {}
-
-  bool ReportContext(const Context& context) override;
-  void ReportRuns(const std::vector<Run>& reports) override;
-
- protected:
-  virtual void PrintRunData(const Run& result);
-  virtual void PrintHeader(const Run& run);
-
-  OutputOptions output_options_;
-  size_t name_field_width_;
-  UserCounters prev_counters_;
-  bool printed_header_;
-};
-
-class BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter {
- public:
-  JSONReporter() : first_report_(true) {}
-  bool ReportContext(const Context& context) override;
-  void ReportRuns(const std::vector<Run>& reports) override;
-  void Finalize() override;
-
- private:
-  void PrintRunData(const Run& run);
-
-  bool first_report_;
-};
-
-class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
-    "The CSV Reporter will be removed in a future release") CSVReporter
-    : public BenchmarkReporter {
- public:
-  CSVReporter() : printed_header_(false) {}
-  bool ReportContext(const Context& context) override;
-  void ReportRuns(const std::vector<Run>& reports) override;
-
- private:
-  void PrintRunData(const Run& run);
-
-  bool printed_header_;
-  std::set<std::string> user_counter_names_;
-};
-
-inline const char* GetTimeUnitString(TimeUnit unit) {
-  switch (unit) {
-    case kSecond:
-      return "s";
-    case kMillisecond:
-      return "ms";
-    case kMicrosecond:
-      return "us";
-    case kNanosecond:
-      return "ns";
-  }
-  BENCHMARK_UNREACHABLE();
-}
-
-inline double GetTimeUnitMultiplier(TimeUnit unit) {
-  switch (unit) {
-    case kSecond:
-      return 1;
-    case kMillisecond:
-      return 1e3;
-    case kMicrosecond:
-      return 1e6;
-    case kNanosecond:
-      return 1e9;
-  }
-  BENCHMARK_UNREACHABLE();
-}
-
-// Creates a list of integer values for the given range and multiplier.
-// This can be used together with ArgsProduct() to allow multiple ranges
-// with different multipliers.
-// Example:
-// ArgsProduct({
-//   CreateRange(0, 1024, /*multi=*/32),
-//   CreateRange(0, 100, /*multi=*/4),
-//   CreateDenseRange(0, 4, /*step=*/1),
-// });
-BENCHMARK_EXPORT
-std::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi);
-
-// Creates a list of integer values for the given range and step.
-BENCHMARK_EXPORT
-std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step);
-
-}  // namespace benchmark
-
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
+#include "benchmark/benchmark_api.h"
+#include "benchmark/counter.h"
+#include "benchmark/macros.h"
+#include "benchmark/managers.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
+#include "benchmark/statistics.h"
+#include "benchmark/sysinfo.h"
+#include "benchmark/types.h"
+#include "benchmark/utils.h"
 
 #endif  // BENCHMARK_BENCHMARK_H_
diff --git a/include/benchmark/benchmark_api.h b/include/benchmark/benchmark_api.h
new file mode 100644
index 0000000..6d98aba
--- /dev/null
+++ b/include/benchmark/benchmark_api.h
@@ -0,0 +1,292 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_BENCHMARK_API_H_
+#define BENCHMARK_BENCHMARK_API_H_
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "benchmark/counter.h"
+#include "benchmark/macros.h"
+#include "benchmark/state.h"
+#include "benchmark/statistics.h"
+#include "benchmark/types.h"
+
+namespace benchmark {
+
+const char kDefaultMinTimeStr[] = "0.5s";
+
+BENCHMARK_EXPORT void MaybeReenterWithoutASLR(int, char**);
+
+BENCHMARK_EXPORT std::string GetBenchmarkVersion();
+
+BENCHMARK_EXPORT void PrintDefaultHelp();
+
+BENCHMARK_EXPORT void Initialize(int* argc, char** argv,
+                                 void (*HelperPrintf)() = PrintDefaultHelp);
+BENCHMARK_EXPORT void Shutdown();
+
+BENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);
+
+BENCHMARK_EXPORT std::string GetBenchmarkFilter();
+
+BENCHMARK_EXPORT void SetBenchmarkFilter(std::string value);
+
+BENCHMARK_EXPORT int32_t GetBenchmarkVerbosity();
+
+BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
+
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);
+
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
+
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(
+    BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
+                       BenchmarkReporter* file_reporter, std::string spec);
+
+BENCHMARK_EXPORT TimeUnit GetDefaultTimeUnit();
+
+BENCHMARK_EXPORT void SetDefaultTimeUnit(TimeUnit unit);
+
+BENCHMARK_EXPORT
+void AddCustomContext(std::string key, std::string value);
+
+struct ThreadRunnerBase {
+  virtual ~ThreadRunnerBase() {}
+  virtual void RunThreads(const std::function<void(int)>& fn) = 0;
+};
+
+using threadrunner_factory =
+    std::function<std::unique_ptr<ThreadRunnerBase>(int)>;
+
+namespace internal {
+class BenchmarkFamilies;
+class BenchmarkInstance;
+}  // namespace internal
+
+class BENCHMARK_EXPORT Benchmark {
+ public:
+  virtual ~Benchmark();
+
+  Benchmark* Name(const std::string& name);
+  Benchmark* Arg(int64_t x);
+  Benchmark* Unit(TimeUnit unit);
+  Benchmark* Range(int64_t start, int64_t limit);
+  Benchmark* DenseRange(int64_t start, int64_t limit, int step = 1);
+  Benchmark* Args(const std::vector<int64_t>& args);
+  Benchmark* ArgPair(int64_t x, int64_t y) {
+    std::vector<int64_t> args;
+    args.push_back(x);
+    args.push_back(y);
+    return Args(args);
+  }
+  Benchmark* Ranges(const std::vector<std::pair<int64_t, int64_t>>& ranges);
+  Benchmark* ArgsProduct(const std::vector<std::vector<int64_t>>& arglists);
+  Benchmark* ArgName(const std::string& name);
+  Benchmark* ArgNames(const std::vector<std::string>& names);
+  Benchmark* RangePair(int64_t lo1, int64_t hi1, int64_t lo2, int64_t hi2) {
+    std::vector<std::pair<int64_t, int64_t>> ranges;
+    ranges.push_back(std::make_pair(lo1, hi1));
+    ranges.push_back(std::make_pair(lo2, hi2));
+    return Ranges(ranges);
+  }
+  Benchmark* Setup(callback_function&&);
+  Benchmark* Setup(const callback_function&);
+  Benchmark* Teardown(callback_function&&);
+  Benchmark* Teardown(const callback_function&);
+  Benchmark* Apply(const std::function<void(Benchmark* benchmark)>&);
+  Benchmark* RangeMultiplier(int multiplier);
+  Benchmark* MinTime(double t);
+  Benchmark* MinWarmUpTime(double t);
+  Benchmark* Iterations(IterationCount n);
+  Benchmark* Repetitions(int n);
+  Benchmark* ReportAggregatesOnly(bool value = true);
+  Benchmark* DisplayAggregatesOnly(bool value = true);
+  Benchmark* MeasureProcessCPUTime();
+  Benchmark* UseRealTime();
+  Benchmark* UseManualTime();
+  Benchmark* Complexity(BigO complexity = benchmark::oAuto);
+  Benchmark* Complexity(BigOFunc* complexity);
+  Benchmark* ComputeStatistics(const std::string& name,
+                               StatisticsFunc* statistics,
+                               StatisticUnit unit = kTime);
+  Benchmark* Threads(int t);
+  Benchmark* ThreadRange(int min_threads, int max_threads);
+  Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1);
+  Benchmark* ThreadPerCpu();
+  Benchmark* ThreadRunner(threadrunner_factory&& factory);
+
+  virtual void Run(State& state) = 0;
+
+  TimeUnit GetTimeUnit() const;
+
+ protected:
+  explicit Benchmark(const std::string& name);
+  void SetName(const std::string& name);
+
+ public:
+  const char* GetName() const;
+  int ArgsCnt() const;
+  const char* GetArgName(int arg) const;
+
+ private:
+  friend class internal::BenchmarkFamilies;
+  friend class internal::BenchmarkInstance;
+
+  std::string name_;
+  internal::AggregationReportMode aggregation_report_mode_;
+  std::vector<std::string> arg_names_;
+  std::vector<std::vector<int64_t>> args_;
+
+  TimeUnit time_unit_;
+  bool use_default_time_unit_;
+
+  int range_multiplier_;
+  double min_time_;
+  double min_warmup_time_;
+  IterationCount iterations_;
+  int repetitions_;
+  bool measure_process_cpu_time_;
+  bool use_real_time_;
+  bool use_manual_time_;
+  BigO complexity_;
+  BigOFunc* complexity_lambda_;
+  std::vector<internal::Statistics> statistics_;
+  std::vector<int> thread_counts_;
+
+  callback_function setup_;
+  callback_function teardown_;
+
+  threadrunner_factory threadrunner_;
+
+  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
+};
+
+namespace internal {
+typedef BENCHMARK_DEPRECATED_MSG(
+    "Use ::benchmark::Benchmark instead")::benchmark::Benchmark Benchmark;
+typedef BENCHMARK_DEPRECATED_MSG(
+    "Use ::benchmark::threadrunner_factory instead")::benchmark::
+    threadrunner_factory threadrunner_factory;
+
+typedef void(Function)(State&);
+
+BENCHMARK_EXPORT ::benchmark::Benchmark* RegisterBenchmarkInternal(
+    std::unique_ptr<::benchmark::Benchmark>);
+BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext();
+BENCHMARK_EXPORT void UseCharPointer(char const volatile*);
+BENCHMARK_EXPORT int InitializeStreams();
+BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
+}  // namespace internal
+
+Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn);
+
+template <class Lambda>
+Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
+
+BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
+
+namespace internal {
+class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark {
+ public:
+  FunctionBenchmark(const std::string& name, Function* func)
+      : Benchmark(name), func_(func) {}
+  void Run(State& st) override;
+
+ private:
+  Function* func_;
+};
+
+template <class Lambda>
+class LambdaBenchmark : public benchmark::Benchmark {
+ public:
+  void Run(State& st) override { lambda_(st); }
+  template <class OLambda>
+  LambdaBenchmark(const std::string& name, OLambda&& lam)
+      : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {}
+
+ private:
+  LambdaBenchmark(LambdaBenchmark const&) = delete;
+  Lambda lambda_;
+};
+}  // namespace internal
+
+inline Benchmark* RegisterBenchmark(const std::string& name,
+                                    internal::Function* fn) {
+  return internal::RegisterBenchmarkInternal(
+      ::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
+                                                                      fn));
+}
+
+template <class Lambda>
+Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
+  using BenchType =
+      internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
+  return internal::RegisterBenchmarkInternal(
+      ::benchmark::internal::make_unique<BenchType>(name,
+                                                    std::forward<Lambda>(fn)));
+}
+
+template <class Lambda, class... Args>
+Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
+                             Args&&... args) {
+  return benchmark::RegisterBenchmark(
+      name, [=](benchmark::State& st) { fn(st, args...); });
+}
+
+class Fixture : public Benchmark {
+ public:
+  Fixture() : Benchmark("") {}
+  void Run(State& st) override {
+    this->SetUp(st);
+    this->BenchmarkCase(st);
+    this->TearDown(st);
+  }
+  virtual void SetUp(const State&) {}
+  virtual void TearDown(const State&) {}
+  virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); }
+  virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); }
+
+ protected:
+  virtual void BenchmarkCase(State&) = 0;
+};
+
+BENCHMARK_EXPORT
+std::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi);
+
+BENCHMARK_EXPORT
+std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step);
+
+}  // namespace benchmark
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif  // BENCHMARK_BENCHMARK_API_H_
diff --git a/include/benchmark/counter.h b/include/benchmark/counter.h
new file mode 100644
index 0000000..8db5d8d
--- /dev/null
+++ b/include/benchmark/counter.h
@@ -0,0 +1,80 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_COUNTER_H_
+#define BENCHMARK_COUNTER_H_
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif
+
+#include <map>
+#include <string>
+
+#include "benchmark/macros.h"
+#include "benchmark/types.h"
+
+namespace benchmark {
+
+class BENCHMARK_EXPORT Counter {
+ public:
+  enum Flags {
+    kDefaults = 0,
+    kIsRate = 1 << 0,
+    kAvgThreads = 1 << 1,
+    kAvgThreadsRate = kIsRate | kAvgThreads,
+    kIsIterationInvariant = 1 << 2,
+    kIsIterationInvariantRate = kIsRate | kIsIterationInvariant,
+    kAvgIterations = 1 << 3,
+    kAvgIterationsRate = kIsRate | kAvgIterations,
+    kInvert = 1 << 31
+  };
+
+  enum OneK { kIs1000 = 1000, kIs1024 = 1024 };
+
+  double value;
+  Flags flags;
+  OneK oneK;
+
+  BENCHMARK_ALWAYS_INLINE
+  Counter(double v = 0., Flags f = kDefaults, OneK k = kIs1000)
+      : value(v), flags(f), oneK(k) {}
+
+  BENCHMARK_ALWAYS_INLINE operator double const&() const { return value; }
+  BENCHMARK_ALWAYS_INLINE operator double&() { return value; }
+};
+
+Counter::Flags inline operator|(const Counter::Flags& LHS,
+                                const Counter::Flags& RHS) {
+  return static_cast<Counter::Flags>(static_cast<int>(LHS) |
+                                     static_cast<int>(RHS));
+}
+
+using UserCounters = std::map<std::string, Counter>;
+
+namespace internal {
+void Finish(UserCounters* l, IterationCount iterations, double cpu_time,
+            double num_threads);
+void Increment(UserCounters* l, UserCounters const& r);
+bool SameNames(UserCounters const& l, UserCounters const& r);
+}  // namespace internal
+
+}  // namespace benchmark
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif  // BENCHMARK_COUNTER_H_
diff --git a/include/benchmark/macros.h b/include/benchmark/macros.h
new file mode 100644
index 0000000..17f19ac
--- /dev/null
+++ b/include/benchmark/macros.h
@@ -0,0 +1,136 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_MACROS_H_
+#define BENCHMARK_MACROS_H_
+
+#if defined(_MSC_VER)
+#include <intrin.h>
+#endif
+
+#include <stdint.h>
+
+#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&) = delete;                \
+  TypeName& operator=(const TypeName&) = delete
+
+#ifdef BENCHMARK_HAS_CXX17
+#define BENCHMARK_UNUSED [[maybe_unused]]
+#elif defined(__GNUC__) || defined(__clang__)
+#define BENCHMARK_UNUSED __attribute__((unused))
+#else
+#define BENCHMARK_UNUSED
+#endif
+
+#if defined(__clang__)
+#define BENCHMARK_DONT_OPTIMIZE __attribute__((optnone))
+#elif defined(__GNUC__) || defined(__GNUG__)
+#define BENCHMARK_DONT_OPTIMIZE __attribute__((optimize(0)))
+#else
+#define BENCHMARK_DONT_OPTIMIZE
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline))
+#elif defined(_MSC_VER) && !defined(__clang__)
+#define BENCHMARK_ALWAYS_INLINE __forceinline
+#define __func__ __FUNCTION__
+#else
+#define BENCHMARK_ALWAYS_INLINE
+#endif
+
+#define BENCHMARK_INTERNAL_TOSTRING2(x) #x
+#define BENCHMARK_INTERNAL_TOSTRING(x) BENCHMARK_INTERNAL_TOSTRING2(x)
+
+#if (defined(__GNUC__) && !defined(__NVCC__) && !defined(__NVCOMPILER)) || \
+    defined(__clang__)
+#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
+#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
+#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
+  _Pragma("GCC diagnostic push")             \
+      _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("GCC diagnostic pop")
+#elif defined(__NVCOMPILER)
+#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y)
+#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
+#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
+  _Pragma("diagnostic push")                 \
+      _Pragma("diag_suppress deprecated_entity_with_custom_message")
+#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
+#elif defined(_MSC_VER)
+#define BENCHMARK_BUILTIN_EXPECT(x, y) x
+#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
+#define BENCHMARK_WARNING_MSG(msg)                           \
+  __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
+      __LINE__) ") : warning note: " msg))
+#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
+  __pragma(warning(push)) __pragma(warning(disable : 4996))
+#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
+#else
+#define BENCHMARK_BUILTIN_EXPECT(x, y) x
+#define BENCHMARK_DEPRECATED_MSG(msg)
+#define BENCHMARK_WARNING_MSG(msg)                           \
+  __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
+      __LINE__) ") : warning note: " msg))
+#define BENCHMARK_DISABLE_DEPRECATED_WARNING
+#define BENCHMARK_RESTORE_DEPRECATED_WARNING
+#endif
+
+#if defined(__GNUC__) && !defined(__clang__)
+#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#if defined(__GNUC__) || __has_builtin(__builtin_unreachable)
+#define BENCHMARK_UNREACHABLE() __builtin_unreachable()
+#elif defined(_MSC_VER)
+#define BENCHMARK_UNREACHABLE() __assume(false)
+#else
+#define BENCHMARK_UNREACHABLE() ((void)0)
+#endif
+
+#if defined(__GNUC__)
+#if defined(__i386__) || defined(__x86_64__)
+#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
+#elif defined(__powerpc64__)
+#define BENCHMARK_INTERNAL_CACHELINE_SIZE 128
+#elif defined(__aarch64__)
+#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
+#elif defined(__arm__)
+#if defined(__ARM_ARCH_5T__)
+#define BENCHMARK_INTERNAL_CACHELINE_SIZE 32
+#elif defined(__ARM_ARCH_7A__)
+#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
+#endif
+#endif
+#endif
+
+#ifndef BENCHMARK_INTERNAL_CACHELINE_SIZE
+#define BENCHMARK_INTERNAL_CACHELINE_SIZE 64
+#endif
+
+#if defined(__GNUC__)
+#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
+  __attribute__((aligned(BENCHMARK_INTERNAL_CACHELINE_SIZE)))
+#elif defined(_MSC_VER)
+#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED \
+  __declspec(align(BENCHMARK_INTERNAL_CACHELINE_SIZE))
+#else
+#define BENCHMARK_INTERNAL_CACHELINE_ALIGNED
+#endif
+
+#endif  // BENCHMARK_MACROS_H_
diff --git a/include/benchmark/managers.h b/include/benchmark/managers.h
new file mode 100644
index 0000000..e8b6cd4
--- /dev/null
+++ b/include/benchmark/managers.h
@@ -0,0 +1,66 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_MANAGERS_H_
+#define BENCHMARK_MANAGERS_H_
+
+#include <stdint.h>
+
+#include <limits>
+
+#include "benchmark/macros.h"
+#include "benchmark/types.h"
+
+namespace benchmark {
+
+class MemoryManager {
+ public:
+  static constexpr int64_t TombstoneValue = std::numeric_limits<int64_t>::max();
+
+  struct Result {
+    Result()
+        : num_allocs(0),
+          max_bytes_used(0),
+          total_allocated_bytes(TombstoneValue),
+          net_heap_growth(TombstoneValue),
+          memory_iterations(0) {}
+
+    int64_t num_allocs;
+    int64_t max_bytes_used;
+    int64_t total_allocated_bytes;
+    int64_t net_heap_growth;
+    IterationCount memory_iterations;
+  };
+
+  virtual ~MemoryManager() {}
+  virtual void Start() = 0;
+  virtual void Stop(Result& result) = 0;
+};
+
+BENCHMARK_EXPORT
+void RegisterMemoryManager(MemoryManager* memory_manager);
+
+class ProfilerManager {
+ public:
+  virtual ~ProfilerManager() {}
+  virtual void AfterSetupStart() = 0;
+  virtual void BeforeTeardownStop() = 0;
+};
+
+BENCHMARK_EXPORT
+void RegisterProfilerManager(ProfilerManager* profiler_manager);
+
+}  // namespace benchmark
+
+#endif  // BENCHMARK_MANAGERS_H_
diff --git a/include/benchmark/registration.h b/include/benchmark/registration.h
new file mode 100644
index 0000000..5ac08de
--- /dev/null
+++ b/include/benchmark/registration.h
@@ -0,0 +1,258 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_REGISTRATION_H_
+#define BENCHMARK_REGISTRATION_H_
+
+#include "benchmark/benchmark_api.h"
+#include "benchmark/macros.h"
+
+#if defined(__clang__)
+#define BENCHMARK_DISABLE_COUNTER_WARNING                            \
+  _Pragma("GCC diagnostic push")                                     \
+      _Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \
+          _Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"")
+#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop")
+#else
+#define BENCHMARK_DISABLE_COUNTER_WARNING
+#define BENCHMARK_RESTORE_COUNTER_WARNING
+#endif
+
+BENCHMARK_DISABLE_COUNTER_WARNING
+#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
+#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
+#else
+#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
+#endif
+BENCHMARK_RESTORE_COUNTER_WARNING
+
+#define BENCHMARK_PRIVATE_NAME(...)                                      \
+  BENCHMARK_PRIVATE_CONCAT(benchmark_uniq_, BENCHMARK_PRIVATE_UNIQUE_ID, \
+                           __VA_ARGS__)
+
+#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c)
+#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c
+#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
+  BaseClass##_##Method##_Benchmark
+
+#define BENCHMARK_PRIVATE_DECLARE(n)                                   \
+  BENCHMARK_DISABLE_COUNTER_WARNING                                    \
+  static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \
+      BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED
+
+#define BENCHMARK(...)                                   \
+  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #__VA_ARGS__,                              \
+              static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
+
+#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
+#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)})
+#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t))
+#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi))
+#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \
+  BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}})
+
+#define BENCHMARK_CAPTURE(func, test_case_name, ...)     \
+  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #func "/" #test_case_name,                 \
+              [](::benchmark::State& st) { func(st, __VA_ARGS__); })))
+
+#define BENCHMARK_NAMED(func, test_case_name)            \
+  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #func "/" #test_case_name,                 \
+              static_cast<::benchmark::internal::Function*>(func))))
+
+#define BENCHMARK_TEMPLATE1(n, a)                        \
+  BENCHMARK_PRIVATE_DECLARE(n) =                         \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #n "<" #a ">",                             \
+              static_cast<::benchmark::internal::Function*>(n<a>))))
+
+#define BENCHMARK_TEMPLATE2(n, a, b)                     \
+  BENCHMARK_PRIVATE_DECLARE(n) =                         \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #n "<" #a "," #b ">",                      \
+              static_cast<::benchmark::internal::Function*>(n<a, b>))))
+
+#define BENCHMARK_TEMPLATE(n, ...)                       \
+  BENCHMARK_PRIVATE_DECLARE(n) =                         \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #n "<" #__VA_ARGS__ ">",                   \
+              static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
+
+#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
+  BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
+
+#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
+  BENCHMARK_PRIVATE_DECLARE(func) =                                  \
+      (::benchmark::internal::RegisterBenchmarkInternal(             \
+          ::benchmark::internal::make_unique<                        \
+              ::benchmark::internal::FunctionBenchmark>(             \
+              #func "<" #a "," #b ">"                                \
+                    "/" #test_case_name,                             \
+              [](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
+
+#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method)        \
+  class BaseClass##_##Method##_Benchmark : public BaseClass { \
+   public:                                                    \
+    BaseClass##_##Method##_Benchmark() {                      \
+      this->SetName(#BaseClass "/" #Method);                  \
+    }                                                         \
+                                                              \
+   protected:                                                 \
+    void BenchmarkCase(::benchmark::State&) override;         \
+  };
+
+#define BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
+  class BaseClass##_##Method##_Benchmark : public BaseClass<a> {    \
+   public:                                                          \
+    BaseClass##_##Method##_Benchmark() {                            \
+      this->SetName(#BaseClass "<" #a ">/" #Method);                \
+    }                                                               \
+                                                                    \
+   protected:                                                       \
+    void BenchmarkCase(::benchmark::State&) override;               \
+  };
+
+#define BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
+  class BaseClass##_##Method##_Benchmark : public BaseClass<a, b> {    \
+   public:                                                             \
+    BaseClass##_##Method##_Benchmark() {                               \
+      this->SetName(#BaseClass "<" #a "," #b ">/" #Method);            \
+    }                                                                  \
+                                                                       \
+   protected:                                                          \
+    void BenchmarkCase(::benchmark::State&) override;                  \
+  };
+
+#define BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, ...)       \
+  class BaseClass##_##Method##_Benchmark : public BaseClass<__VA_ARGS__> { \
+   public:                                                                 \
+    BaseClass##_##Method##_Benchmark() {                                   \
+      this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method);             \
+    }                                                                      \
+                                                                           \
+   protected:                                                              \
+    void BenchmarkCase(::benchmark::State&) override;                      \
+  };
+
+#define BENCHMARK_DEFINE_F(BaseClass, Method)    \
+  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_TEMPLATE1_DEFINE_F(BaseClass, Method, a)    \
+  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_TEMPLATE2_DEFINE_F(BaseClass, Method, a, b)    \
+  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, ...)            \
+  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_REGISTER_F(BaseClass, Method) \
+  BENCHMARK_PRIVATE_REGISTER_F(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method))
+
+#define BENCHMARK_PRIVATE_REGISTER_F(TestName)           \
+  BENCHMARK_PRIVATE_DECLARE(TestName) =                  \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<TestName>()))
+
+#define BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
+  BaseClass##_##Method##_BenchmarkTemplate
+
+#define BENCHMARK_TEMPLATE_METHOD_F(BaseClass, Method)              \
+  template <class... Args>                                          \
+  class BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(BaseClass, Method) \
+      : public BaseClass<Args...> {                                 \
+   protected:                                                       \
+    using Base = BaseClass<Args...>;                                \
+    void BenchmarkCase(::benchmark::State&) override;               \
+  };                                                                \
+  template <class... Args>                                          \
+  void BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(                    \
+      BaseClass, Method)<Args...>::BenchmarkCase
+
+#define BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(BaseClass, Method,           \
+                                                 UniqueName, ...)             \
+  class UniqueName : public BENCHMARK_TEMPLATE_PRIVATE_CONCAT_NAME_F(         \
+                         BaseClass, Method)<__VA_ARGS__> {                    \
+   public:                                                                    \
+    UniqueName() { this->SetName(#BaseClass "<" #__VA_ARGS__ ">/" #Method); } \
+  };                                                                          \
+  BENCHMARK_PRIVATE_DECLARE(BaseClass##_##Method##_Benchmark) =               \
+      (::benchmark::internal::RegisterBenchmarkInternal(                      \
+          ::benchmark::internal::make_unique<UniqueName>()))
+
+#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...)    \
+  BENCHMARK_DISABLE_COUNTER_WARNING                                 \
+  BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(                         \
+      BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
+      __VA_ARGS__)                                                  \
+  BENCHMARK_RESTORE_COUNTER_WARNING
+
+#define BENCHMARK_F(BaseClass, Method)           \
+  BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
+  BENCHMARK_REGISTER_F(BaseClass, Method);       \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_TEMPLATE1_F(BaseClass, Method, a)           \
+  BENCHMARK_TEMPLATE1_PRIVATE_DECLARE_F(BaseClass, Method, a) \
+  BENCHMARK_REGISTER_F(BaseClass, Method);                    \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_TEMPLATE2_F(BaseClass, Method, a, b)           \
+  BENCHMARK_TEMPLATE2_PRIVATE_DECLARE_F(BaseClass, Method, a, b) \
+  BENCHMARK_REGISTER_F(BaseClass, Method);                       \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_TEMPLATE_F(BaseClass, Method, ...)                   \
+  BENCHMARK_TEMPLATE_PRIVATE_DECLARE_F(BaseClass, Method, __VA_ARGS__) \
+  void BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::BenchmarkCase
+
+#define BENCHMARK_MAIN()                                                \
+  int main(int argc, char** argv) {                                     \
+    benchmark::MaybeReenterWithoutASLR(argc, argv);                     \
+    char arg0_default[] = "benchmark";                                  \
+    char* args_default = reinterpret_cast<char*>(arg0_default);         \
+    if (!argv) {                                                        \
+      argc = 1;                                                         \
+      argv = &args_default;                                             \
+    }                                                                   \
+    ::benchmark::Initialize(&argc, argv);                               \
+    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
+    ::benchmark::RunSpecifiedBenchmarks();                              \
+    ::benchmark::Shutdown();                                            \
+    return 0;                                                           \
+  }                                                                     \
+  int main(int, char**)
+
+#endif  // BENCHMARK_REGISTRATION_H_
diff --git a/include/benchmark/reporter.h b/include/benchmark/reporter.h
new file mode 100644
index 0000000..be242be
--- /dev/null
+++ b/include/benchmark/reporter.h
@@ -0,0 +1,238 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_REPORTER_H_
+#define BENCHMARK_REPORTER_H_
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+// C4251: <symbol> needs to have dll-interface to be used by clients of class
+#pragma warning(disable : 4251)
+#endif
+
+#include <cassert>
+#include <iostream>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "benchmark/counter.h"
+#include "benchmark/macros.h"
+#include "benchmark/managers.h"
+#include "benchmark/statistics.h"
+#include "benchmark/sysinfo.h"
+#include "benchmark/types.h"
+
+namespace benchmark {
+
+struct BENCHMARK_EXPORT BenchmarkName {
+  std::string function_name;
+  std::string args;
+  std::string min_time;
+  std::string min_warmup_time;
+  std::string iterations;
+  std::string repetitions;
+  std::string time_type;
+  std::string threads;
+
+  std::string str() const;
+};
+
+class BENCHMARK_EXPORT BenchmarkReporter {
+ public:
+  struct Context {
+    CPUInfo const& cpu_info;
+    SystemInfo const& sys_info;
+    size_t name_field_width = 0;
+    static const char* executable_name;
+    Context();
+  };
+
+  struct BENCHMARK_EXPORT Run {
+    static const int64_t no_repetition_index = -1;
+    enum RunType { RT_Iteration, RT_Aggregate };
+
+    Run()
+        : run_type(RT_Iteration),
+          aggregate_unit(kTime),
+          skipped(internal::NotSkipped),
+          iterations(1),
+          threads(1),
+          time_unit(kNanosecond),
+          real_accumulated_time(0),
+          cpu_accumulated_time(0),
+          max_heapbytes_used(0),
+          use_real_time_for_initial_big_o(false),
+          complexity(oNone),
+          complexity_lambda(),
+          complexity_n(0),
+          statistics(),
+          report_big_o(false),
+          report_rms(false),
+          allocs_per_iter(0.0) {}
+
+    std::string benchmark_name() const;
+    BenchmarkName run_name;
+    int64_t family_index;
+    int64_t per_family_instance_index;
+    RunType run_type;
+    std::string aggregate_name;
+    StatisticUnit aggregate_unit;
+    std::string report_label;
+    internal::Skipped skipped;
+    std::string skip_message;
+
+    IterationCount iterations;
+    int64_t threads;
+    int64_t repetition_index;
+    int64_t repetitions;
+    TimeUnit time_unit;
+    double real_accumulated_time;
+    double cpu_accumulated_time;
+
+    double GetAdjustedRealTime() const;
+    double GetAdjustedCPUTime() const;
+
+    double max_heapbytes_used;
+    bool use_real_time_for_initial_big_o;
+    BigO complexity;
+    BigOFunc* complexity_lambda;
+    ComplexityN complexity_n;
+    const std::vector<internal::Statistics>* statistics;
+    bool report_big_o;
+    bool report_rms;
+    UserCounters counters;
+    MemoryManager::Result memory_result;
+    double allocs_per_iter;
+  };
+
+  struct PerFamilyRunReports {
+    PerFamilyRunReports() : num_runs_total(0), num_runs_done(0) {}
+    int num_runs_total;
+    int num_runs_done;
+    std::vector<BenchmarkReporter::Run> Runs;
+  };
+
+  BenchmarkReporter();
+  virtual bool ReportContext(const Context& context) = 0;
+  virtual void ReportRunsConfig(double /*min_time*/,
+                                bool /*has_explicit_iters*/,
+                                IterationCount /*iters*/) {}
+  virtual void ReportRuns(const std::vector<Run>& report) = 0;
+  virtual void Finalize() {}
+
+  void SetOutputStream(std::ostream* out) {
+    assert(out);
+    output_stream_ = out;
+  }
+  void SetErrorStream(std::ostream* err) {
+    assert(err);
+    error_stream_ = err;
+  }
+  std::ostream& GetOutputStream() const { return *output_stream_; }
+  std::ostream& GetErrorStream() const { return *error_stream_; }
+  virtual ~BenchmarkReporter();
+  static void PrintBasicContext(std::ostream* out, Context const& context);
+
+ private:
+  std::ostream* output_stream_;
+  std::ostream* error_stream_;
+};
+
+class BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter {
+ public:
+  enum OutputOptions {
+    OO_None = 0,
+    OO_Color = 1,
+    OO_Tabular = 2,
+    OO_ColorTabular = OO_Color | OO_Tabular,
+    OO_Defaults = OO_ColorTabular
+  };
+  explicit ConsoleReporter(OutputOptions opts_ = OO_Defaults)
+      : output_options_(opts_), name_field_width_(0), printed_header_(false) {}
+
+  bool ReportContext(const Context& context) override;
+  void ReportRuns(const std::vector<Run>& reports) override;
+
+ protected:
+  virtual void PrintRunData(const Run& result);
+  virtual void PrintHeader(const Run& run);
+
+  OutputOptions output_options_;
+  size_t name_field_width_;
+  UserCounters prev_counters_;
+  bool printed_header_;
+};
+
+class BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter {
+ public:
+  JSONReporter() : first_report_(true) {}
+  bool ReportContext(const Context& context) override;
+  void ReportRuns(const std::vector<Run>& reports) override;
+  void Finalize() override;
+
+ private:
+  void PrintRunData(const Run& run);
+  bool first_report_;
+};
+
+class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
+    "The CSV Reporter will be removed in a future release") CSVReporter
+    : public BenchmarkReporter {
+ public:
+  CSVReporter() : printed_header_(false) {}
+  bool ReportContext(const Context& context) override;
+  void ReportRuns(const std::vector<Run>& reports) override;
+
+ private:
+  void PrintRunData(const Run& run);
+  bool printed_header_;
+  std::set<std::string> user_counter_names_;
+};
+
+inline const char* GetTimeUnitString(TimeUnit unit) {
+  switch (unit) {
+    case kSecond:
+      return "s";
+    case kMillisecond:
+      return "ms";
+    case kMicrosecond:
+      return "us";
+    case kNanosecond:
+      return "ns";
+  }
+  BENCHMARK_UNREACHABLE();
+}
+
+inline double GetTimeUnitMultiplier(TimeUnit unit) {
+  switch (unit) {
+    case kSecond:
+      return 1;
+    case kMillisecond:
+      return 1e3;
+    case kMicrosecond:
+      return 1e6;
+    case kNanosecond:
+      return 1e9;
+  }
+  BENCHMARK_UNREACHABLE();
+}
+
+}  // namespace benchmark
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif  // BENCHMARK_REPORTER_H_
diff --git a/include/benchmark/state.h b/include/benchmark/state.h
new file mode 100644
index 0000000..e9cdf05
--- /dev/null
+++ b/include/benchmark/state.h
@@ -0,0 +1,265 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_STATE_H_
+#define BENCHMARK_STATE_H_
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4251 4324)
+#endif
+
+#include <cassert>
+#include <string>
+#include <vector>
+
+#include "benchmark/counter.h"
+#include "benchmark/macros.h"
+#include "benchmark/statistics.h"
+#include "benchmark/types.h"
+
+namespace benchmark {
+
+namespace internal {
+class BenchmarkInstance;
+class ThreadTimer;
+class ThreadManager;
+class PerfCountersMeasurement;
+}  // namespace internal
+
+class ProfilerManager;
+
+class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
+ public:
+  struct StateIterator;
+  friend struct StateIterator;
+
+  inline BENCHMARK_ALWAYS_INLINE StateIterator begin();
+  inline BENCHMARK_ALWAYS_INLINE StateIterator end();
+
+  inline bool KeepRunning();
+
+  inline bool KeepRunningBatch(IterationCount n);
+
+  void PauseTiming();
+
+  void ResumeTiming();
+
+  void SkipWithMessage(const std::string& msg);
+
+  void SkipWithError(const std::string& msg);
+
+  bool skipped() const { return internal::NotSkipped != skipped_; }
+
+  bool error_occurred() const { return internal::SkippedWithError == skipped_; }
+
+  void SetIterationTime(double seconds);
+
+  BENCHMARK_ALWAYS_INLINE
+  void SetBytesProcessed(int64_t bytes) {
+    counters["bytes_per_second"] =
+        Counter(static_cast<double>(bytes), Counter::kIsRate, Counter::kIs1024);
+  }
+
+  BENCHMARK_ALWAYS_INLINE
+  int64_t bytes_processed() const {
+    if (counters.find("bytes_per_second") != counters.end())
+      return static_cast<int64_t>(counters.at("bytes_per_second"));
+    return 0;
+  }
+
+  BENCHMARK_ALWAYS_INLINE
+  void SetComplexityN(ComplexityN complexity_n) {
+    complexity_n_ = complexity_n;
+  }
+
+  BENCHMARK_ALWAYS_INLINE
+  ComplexityN complexity_length_n() const { return complexity_n_; }
+
+  BENCHMARK_ALWAYS_INLINE
+  void SetItemsProcessed(int64_t items) {
+    counters["items_per_second"] =
+        Counter(static_cast<double>(items), benchmark::Counter::kIsRate);
+  }
+
+  BENCHMARK_ALWAYS_INLINE
+  int64_t items_processed() const {
+    if (counters.find("items_per_second") != counters.end())
+      return static_cast<int64_t>(counters.at("items_per_second"));
+    return 0;
+  }
+
+  void SetLabel(const std::string& label);
+
+  BENCHMARK_ALWAYS_INLINE
+  int64_t range(std::size_t pos = 0) const {
+    assert(range_.size() > pos);
+    return range_[pos];
+  }
+
+  BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead")
+  int64_t range_x() const { return range(0); }
+
+  BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead")
+  int64_t range_y() const { return range(1); }
+
+  BENCHMARK_ALWAYS_INLINE
+  int threads() const { return threads_; }
+
+  BENCHMARK_ALWAYS_INLINE
+  int thread_index() const { return thread_index_; }
+
+  BENCHMARK_ALWAYS_INLINE
+  IterationCount iterations() const {
+    if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) {
+      return 0;
+    }
+    return max_iterations - total_iterations_ + batch_leftover_;
+  }
+
+  BENCHMARK_ALWAYS_INLINE
+  std::string name() const { return name_; }
+
+  size_t range_size() const { return range_.size(); }
+
+ private:
+  IterationCount total_iterations_;
+
+  IterationCount batch_leftover_;
+
+ public:
+  const IterationCount max_iterations;
+
+ private:
+  bool started_;
+  bool finished_;
+  internal::Skipped skipped_;
+
+  std::vector<int64_t> range_;
+
+  ComplexityN complexity_n_;
+
+ public:
+  UserCounters counters;
+
+ private:
+  State(std::string name, IterationCount max_iters,
+        const std::vector<int64_t>& ranges, int thread_i, int n_threads,
+        internal::ThreadTimer* timer, internal::ThreadManager* manager,
+        internal::PerfCountersMeasurement* perf_counters_measurement,
+        ProfilerManager* profiler_manager);
+
+  void StartKeepRunning();
+  inline bool KeepRunningInternal(IterationCount n, bool is_batch);
+  void FinishKeepRunning();
+
+  const std::string name_;
+  const int thread_index_;
+  const int threads_;
+
+  internal::ThreadTimer* const timer_;
+  internal::ThreadManager* const manager_;
+  internal::PerfCountersMeasurement* const perf_counters_measurement_;
+  ProfilerManager* const profiler_manager_;
+
+  friend class internal::BenchmarkInstance;
+};
+
+inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunning() {
+  return KeepRunningInternal(1, /*is_batch=*/false);
+}
+
+inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningBatch(IterationCount n) {
+  return KeepRunningInternal(n, /*is_batch=*/true);
+}
+
+inline BENCHMARK_ALWAYS_INLINE bool State::KeepRunningInternal(IterationCount n,
+                                                               bool is_batch) {
+  assert(n > 0);
+  assert(is_batch || n == 1);
+  if (BENCHMARK_BUILTIN_EXPECT(total_iterations_ >= n, true)) {
+    total_iterations_ -= n;
+    return true;
+  }
+  if (!started_) {
+    StartKeepRunning();
+    if (!skipped() && total_iterations_ >= n) {
+      total_iterations_ -= n;
+      return true;
+    }
+  }
+  if (is_batch && total_iterations_ != 0) {
+    batch_leftover_ = n - total_iterations_;
+    total_iterations_ = 0;
+    return true;
+  }
+  FinishKeepRunning();
+  return false;
+}
+
+struct State::StateIterator {
+  struct BENCHMARK_UNUSED Value {};
+  typedef std::forward_iterator_tag iterator_category;
+  typedef Value value_type;
+  typedef Value reference;
+  typedef Value pointer;
+  typedef std::ptrdiff_t difference_type;
+
+ private:
+  friend class State;
+  BENCHMARK_ALWAYS_INLINE
+  StateIterator() : cached_(0), parent_() {}
+
+  BENCHMARK_ALWAYS_INLINE
+  explicit StateIterator(State* st)
+      : cached_(st->skipped() ? 0 : st->max_iterations), parent_(st) {}
+
+ public:
+  BENCHMARK_ALWAYS_INLINE
+  Value operator*() const { return Value(); }
+
+  BENCHMARK_ALWAYS_INLINE
+  StateIterator& operator++() {
+    assert(cached_ > 0);
+    --cached_;
+    return *this;
+  }
+
+  BENCHMARK_ALWAYS_INLINE
+  bool operator!=(StateIterator const&) const {
+    if (BENCHMARK_BUILTIN_EXPECT(cached_ != 0, true)) return true;
+    parent_->FinishKeepRunning();
+    return false;
+  }
+
+ private:
+  IterationCount cached_;
+  State* const parent_;
+};
+
+inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::begin() {
+  return StateIterator(this);
+}
+inline BENCHMARK_ALWAYS_INLINE State::StateIterator State::end() {
+  StartKeepRunning();
+  return StateIterator();
+}
+
+}  // namespace benchmark
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif  // BENCHMARK_STATE_H_
diff --git a/include/benchmark/statistics.h b/include/benchmark/statistics.h
new file mode 100644
index 0000000..04f01b1
--- /dev/null
+++ b/include/benchmark/statistics.h
@@ -0,0 +1,65 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_STATISTICS_H_
+#define BENCHMARK_STATISTICS_H_
+
+#include <string>
+#include <vector>
+
+#include "benchmark/types.h"
+
+namespace benchmark {
+
+enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda };
+
+typedef int64_t ComplexityN;
+
+enum StatisticUnit { kTime, kPercentage };
+
+typedef double(BigOFunc)(ComplexityN);
+
+typedef double(StatisticsFunc)(const std::vector<double>&);
+
+namespace internal {
+struct Statistics {
+  std::string name_;
+  StatisticsFunc* compute_;
+  StatisticUnit unit_;
+
+  Statistics(const std::string& name, StatisticsFunc* compute,
+             StatisticUnit unit = kTime)
+      : name_(name), compute_(compute), unit_(unit) {}
+};
+
+enum AggregationReportMode : unsigned {
+  ARM_Unspecified = 0,
+  ARM_Default = 1U << 0U,
+  ARM_FileReportAggregatesOnly = 1U << 1U,
+  ARM_DisplayReportAggregatesOnly = 1U << 2U,
+  ARM_ReportAggregatesOnly =
+      ARM_FileReportAggregatesOnly | ARM_DisplayReportAggregatesOnly
+};
+
+enum Skipped : unsigned {
+  NotSkipped = 0,
+  SkippedWithMessage,
+  SkippedWithError
+};
+
+}  // namespace internal
+
+}  // namespace benchmark
+
+#endif  // BENCHMARK_STATISTICS_H_
diff --git a/include/benchmark/sysinfo.h b/include/benchmark/sysinfo.h
new file mode 100644
index 0000000..711e64d
--- /dev/null
+++ b/include/benchmark/sysinfo.h
@@ -0,0 +1,71 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_SYSINFO_H_
+#define BENCHMARK_SYSINFO_H_
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4251)
+#endif
+
+#include <string>
+#include <vector>
+
+#include "benchmark/macros.h"
+
+namespace benchmark {
+
+struct BENCHMARK_EXPORT CPUInfo {
+  struct CacheInfo {
+    std::string type;
+    int level;
+    int size;
+    int num_sharing;
+  };
+
+  enum Scaling { UNKNOWN, ENABLED, DISABLED };
+
+  int num_cpus;
+  Scaling scaling;
+  double cycles_per_second;
+  std::vector<CacheInfo> caches;
+  std::vector<double> load_avg;
+
+  static const CPUInfo& Get();
+
+ private:
+  CPUInfo();
+  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(CPUInfo);
+};
+
+struct BENCHMARK_EXPORT SystemInfo {
+  enum class ASLR { UNKNOWN, ENABLED, DISABLED };
+
+  std::string name;
+  ASLR ASLRStatus;
+  static const SystemInfo& Get();
+
+ private:
+  SystemInfo();
+  BENCHMARK_DISALLOW_COPY_AND_ASSIGN(SystemInfo);
+};
+
+}  // namespace benchmark
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif  // BENCHMARK_SYSINFO_H_
diff --git a/include/benchmark/types.h b/include/benchmark/types.h
new file mode 100644
index 0000000..a82ffb9
--- /dev/null
+++ b/include/benchmark/types.h
@@ -0,0 +1,50 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_TYPES_H_
+#define BENCHMARK_TYPES_H_
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "benchmark/export.h"
+
+namespace benchmark {
+
+namespace internal {
+#if (__cplusplus < 201402L || (defined(_MSC_VER) && _MSVC_LANG < 201402L))
+template <typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args&&... args) {
+  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+#else
+using ::std::make_unique;
+#endif
+}  // namespace internal
+
+class BenchmarkReporter;
+class State;
+
+using IterationCount = int64_t;
+
+using callback_function = std::function<void(const benchmark::State&)>;
+
+enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond, kSecond };
+
+}  // namespace benchmark
+
+#endif  // BENCHMARK_TYPES_H_
diff --git a/include/benchmark/utils.h b/include/benchmark/utils.h
new file mode 100644
index 0000000..2be0d3f
--- /dev/null
+++ b/include/benchmark/utils.h
@@ -0,0 +1,152 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef BENCHMARK_UTILS_H_
+#define BENCHMARK_UTILS_H_
+
+#include <atomic>
+#include <type_traits>
+#include <utility>
+
+#include "benchmark/macros.h"
+
+namespace benchmark {
+
+namespace internal {
+BENCHMARK_EXPORT void UseCharPointer(char const volatile*);
+}
+
+#if (!defined(__GNUC__) && !defined(__clang__)) || defined(__pnacl__) || \
+    defined(__EMSCRIPTEN__)
+#define BENCHMARK_HAS_NO_INLINE_ASSEMBLY
+#endif
+
+inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() {
+  std::atomic_signal_fence(std::memory_order_acq_rel);
+}
+
+#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY
+#if !defined(__GNUC__) || defined(__llvm__) || defined(__INTEL_COMPILER)
+template <class Tp>
+BENCHMARK_DEPRECATED_MSG(
+    "The const-ref version of this method can permit "
+    "undesired compiler optimizations in benchmarks")
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
+  asm volatile("" : : "r,m"(value) : "memory");
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
+#if defined(__clang__)
+  asm volatile("" : "+r,m"(value) : : "memory");
+#else
+  asm volatile("" : "+m,r"(value) : : "memory");
+#endif
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
+#if defined(__clang__)
+  asm volatile("" : "+r,m"(value) : : "memory");
+#else
+  asm volatile("" : "+m,r"(value) : : "memory");
+#endif
+}
+#elif (__GNUC__ >= 5)
+template <class Tp>
+BENCHMARK_DEPRECATED_MSG(
+    "The const-ref version of this method can permit "
+    "undesired compiler optimizations in benchmarks")
+inline BENCHMARK_ALWAYS_INLINE
+    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
+                            (sizeof(Tp) <= sizeof(Tp*))>::type
+    DoNotOptimize(Tp const& value) {
+  asm volatile("" : : "r,m"(value) : "memory");
+}
+
+template <class Tp>
+BENCHMARK_DEPRECATED_MSG(
+    "The const-ref version of this method can permit "
+    "undesired compiler optimizations in benchmarks")
+inline BENCHMARK_ALWAYS_INLINE
+    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
+                            (sizeof(Tp) > sizeof(Tp*))>::type
+    DoNotOptimize(Tp const& value) {
+  asm volatile("" : : "m"(value) : "memory");
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE
+    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
+                            (sizeof(Tp) <= sizeof(Tp*))>::type
+    DoNotOptimize(Tp& value) {
+  asm volatile("" : "+m,r"(value) : : "memory");
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE
+    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
+                            (sizeof(Tp) > sizeof(Tp*))>::type
+    DoNotOptimize(Tp& value) {
+  asm volatile("" : "+m"(value) : : "memory");
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE
+    typename std::enable_if<std::is_trivially_copyable<Tp>::value &&
+                            (sizeof(Tp) <= sizeof(Tp*))>::type
+    DoNotOptimize(Tp&& value) {
+  asm volatile("" : "+m,r"(value) : : "memory");
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE
+    typename std::enable_if<!std::is_trivially_copyable<Tp>::value ||
+                            (sizeof(Tp) > sizeof(Tp*))>::type
+    DoNotOptimize(Tp&& value) {
+  asm volatile("" : "+m"(value) : : "memory");
+}
+#endif
+
+#elif defined(_MSC_VER)
+template <class Tp>
+BENCHMARK_DEPRECATED_MSG(
+    "The const-ref version of this method can permit "
+    "undesired compiler optimizations in benchmarks")
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
+  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
+  _ReadWriteBarrier();
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
+  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
+  _ReadWriteBarrier();
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
+  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
+  _ReadWriteBarrier();
+}
+#else
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
+  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
+}
+#endif
+
+}  // end namespace benchmark
+
+#endif  // BENCHMARK_UTILS_H_
diff --git a/src/benchmark.cc b/src/benchmark.cc
index fc36fed..acf4d3b 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -12,8 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "benchmark/benchmark.h"
-
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
+#include "benchmark/types.h"
 #include "benchmark_api_internal.h"
 #include "benchmark_runner.h"
 #include "internal_macros.h"
diff --git a/src/benchmark_api_internal.h b/src/benchmark_api_internal.h
index 5b48ea2..0f356da 100644
--- a/src/benchmark_api_internal.h
+++ b/src/benchmark_api_internal.h
@@ -8,7 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/reporter.h"
+#include "benchmark/sysinfo.h"
 #include "commandlineflags.h"
 
 namespace benchmark {
diff --git a/src/benchmark_main.cc b/src/benchmark_main.cc
index 15c76ea..0501643 100644
--- a/src/benchmark_main.cc
+++ b/src/benchmark_main.cc
@@ -12,7 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "benchmark/benchmark.h"
+#include "benchmark/export.h"
+#include "benchmark/registration.h"
 
 BENCHMARK_EXPORT int main(int /*argc*/, char** /*argv*/);
 BENCHMARK_MAIN();
diff --git a/src/benchmark_name.cc b/src/benchmark_name.cc
index 804cfbd..710eb6d 100644
--- a/src/benchmark_name.cc
+++ b/src/benchmark_name.cc
@@ -12,7 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <benchmark/benchmark.h>
+#include "benchmark/export.h"
+#include "benchmark/reporter.h"
 
 namespace benchmark {
 
diff --git a/src/benchmark_register.cc b/src/benchmark_register.cc
index 65e1afc..730d275 100644
--- a/src/benchmark_register.cc
+++ b/src/benchmark_register.cc
@@ -36,7 +36,11 @@
 #include <sstream>
 #include <thread>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/statistics.h"
+#include "benchmark/types.h"
 #include "benchmark_api_internal.h"
 #include "check.h"
 #include "commandlineflags.h"
diff --git a/src/benchmark_runner.cc b/src/benchmark_runner.cc
index fb68867..7efbad4 100644
--- a/src/benchmark_runner.cc
+++ b/src/benchmark_runner.cc
@@ -14,7 +14,11 @@
 
 #include "benchmark_runner.h"
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/managers.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
+#include "benchmark/types.h"
 #include "benchmark_api_internal.h"
 #include "internal_macros.h"
 
diff --git a/src/complexity.cc b/src/complexity.cc
index 4c9ef6d..8fa3f07 100644
--- a/src/complexity.cc
+++ b/src/complexity.cc
@@ -19,7 +19,9 @@
 
 #include <cmath>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/reporter.h"
+#include "benchmark/statistics.h"
+#include "benchmark/types.h"
 #include "check.h"
 
 namespace benchmark {
diff --git a/src/complexity.h b/src/complexity.h
index 0a0679b..06002be 100644
--- a/src/complexity.h
+++ b/src/complexity.h
@@ -21,7 +21,8 @@
 #include <string>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/reporter.h"
+#include "benchmark/statistics.h"
 
 namespace benchmark {
 
diff --git a/src/console_reporter.cc b/src/console_reporter.cc
index a7cde4e..84fe99d 100644
--- a/src/console_reporter.cc
+++ b/src/console_reporter.cc
@@ -21,7 +21,9 @@
 #include <tuple>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/export.h"
+#include "benchmark/reporter.h"
+#include "benchmark/types.h"
 #include "check.h"
 #include "colorprint.h"
 #include "commandlineflags.h"
diff --git a/src/counter.h b/src/counter.h
index 1f5a58e..811a667 100644
--- a/src/counter.h
+++ b/src/counter.h
@@ -12,14 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef BENCHMARK_COUNTER_H_
-#define BENCHMARK_COUNTER_H_
+#ifndef BENCHMARK_SRC_COUNTER_H_
+#define BENCHMARK_SRC_COUNTER_H_
 
-#include "benchmark/benchmark.h"
+#include "benchmark/counter.h"
+#include "benchmark/export.h"
+#include "benchmark/types.h"
 
 namespace benchmark {
 
-// these counter-related functions are hidden to reduce API surface.
 namespace internal {
 void Finish(UserCounters* l, IterationCount iterations, double time,
             double num_threads);
@@ -29,4 +30,4 @@
 
 }  // end namespace benchmark
 
-#endif  // BENCHMARK_COUNTER_H_
+#endif  // BENCHMARK_SRC_COUNTER_H_
diff --git a/src/csv_reporter.cc b/src/csv_reporter.cc
index 0f99804..1665ac5 100644
--- a/src/csv_reporter.cc
+++ b/src/csv_reporter.cc
@@ -16,7 +16,8 @@
 #include <string>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/export.h"
+#include "benchmark/reporter.h"
 #include "check.h"
 #include "complexity.h"
 
diff --git a/src/cycleclock.h b/src/cycleclock.h
index 0671a42..2633f22 100644
--- a/src/cycleclock.h
+++ b/src/cycleclock.h
@@ -23,7 +23,7 @@
 
 #include <cstdint>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/macros.h"
 #include "internal_macros.h"
 
 #if defined(BENCHMARK_OS_MACOSX)
diff --git a/src/json_reporter.cc b/src/json_reporter.cc
index 2b84cd1..ef4636e 100644
--- a/src/json_reporter.cc
+++ b/src/json_reporter.cc
@@ -22,7 +22,10 @@
 #include <tuple>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/export.h"
+#include "benchmark/reporter.h"
+#include "benchmark/types.h"
 #include "complexity.h"
 #include "string_util.h"
 #include "timers.h"
diff --git a/src/perf_counters.h b/src/perf_counters.h
index 4e45344..23cdcc3 100644
--- a/src/perf_counters.h
+++ b/src/perf_counters.h
@@ -16,12 +16,15 @@
 #define BENCHMARK_PERF_COUNTERS_H
 
 #include <array>
+#include <cassert>
 #include <cstdint>
 #include <cstring>
 #include <memory>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/export.h"
+#include "benchmark/macros.h"
+#include "benchmark/utils.h"
 #include "check.h"
 #include "log.h"
 #include "mutex.h"
diff --git a/src/reporter.cc b/src/reporter.cc
index 71926b1..73ca8d0 100644
--- a/src/reporter.cc
+++ b/src/reporter.cc
@@ -12,6 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "benchmark/reporter.h"
+
 #include <cstdlib>
 #include <iostream>
 #include <map>
@@ -19,7 +21,8 @@
 #include <tuple>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/sysinfo.h"
 #include "check.h"
 #include "string_util.h"
 #include "timers.h"
@@ -31,10 +34,10 @@
 
 BenchmarkReporter::~BenchmarkReporter() {}
 
-void BenchmarkReporter::PrintBasicContext(std::ostream *out,
-                                          Context const &context) {
+void BenchmarkReporter::PrintBasicContext(std::ostream* out,
+                                          Context const& context) {
   BM_CHECK(out) << "cannot be null";
-  auto &Out = *out;
+  auto& Out = *out;
 
 #ifndef BENCHMARK_OS_QURT
   // Date/time information is not available on QuRT.
@@ -47,13 +50,13 @@
         << "\n";
   }
 
-  const CPUInfo &info = context.cpu_info;
+  const CPUInfo& info = context.cpu_info;
   Out << "Run on (" << info.num_cpus << " X "
       << (info.cycles_per_second / 1000000.0) << " MHz CPU "
       << ((info.num_cpus > 1) ? "s" : "") << ")\n";
   if (!info.caches.empty()) {
     Out << "CPU Caches:\n";
-    for (const auto &CInfo : info.caches) {
+    for (const auto& CInfo : info.caches) {
       Out << "  L" << CInfo.level << " " << CInfo.type << " "
           << (CInfo.size / 1024) << " KiB";
       if (CInfo.num_sharing != 0) {
@@ -73,11 +76,11 @@
     Out << "\n";
   }
 
-  std::map<std::string, std::string> *global_context =
+  std::map<std::string, std::string>* global_context =
       internal::GetGlobalContext();
 
   if (global_context != nullptr) {
-    for (const auto &kv : *global_context) {
+    for (const auto& kv : *global_context) {
       Out << kv.first << ": " << kv.second << "\n";
     }
   }
@@ -88,7 +91,7 @@
            "overhead.\n";
   }
 
-  const SystemInfo &sysinfo = context.sys_info;
+  const SystemInfo& sysinfo = context.sys_info;
   if (SystemInfo::ASLR::ENABLED == sysinfo.ASLRStatus) {
     Out << "***WARNING*** ASLR is enabled, the results may have unreproducible "
            "noise in them.\n";
@@ -101,7 +104,7 @@
 }
 
 // No initializer because it's already initialized to NULL.
-const char *BenchmarkReporter::Context::executable_name;
+const char* BenchmarkReporter::Context::executable_name;
 
 BenchmarkReporter::Context::Context()
     : cpu_info(CPUInfo::Get()), sys_info(SystemInfo::Get()) {}
diff --git a/src/statistics.cc b/src/statistics.cc
index fc7450e..2c6c858 100644
--- a/src/statistics.cc
+++ b/src/statistics.cc
@@ -21,7 +21,9 @@
 #include <string>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/reporter.h"
+#include "benchmark/statistics.h"
+#include "benchmark/types.h"
 #include "check.h"
 
 namespace benchmark {
diff --git a/src/statistics.h b/src/statistics.h
index 6e5560e..2e56c53 100644
--- a/src/statistics.h
+++ b/src/statistics.h
@@ -18,7 +18,8 @@
 
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/export.h"
+#include "benchmark/reporter.h"
 
 namespace benchmark {
 
diff --git a/src/string_util.cc b/src/string_util.cc
index aa36cf9..ae9667b 100644
--- a/src/string_util.cc
+++ b/src/string_util.cc
@@ -11,7 +11,7 @@
 #include <sstream>
 
 #include "arraysize.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/types.h"
 
 namespace benchmark {
 namespace {
diff --git a/src/string_util.h b/src/string_util.h
index 7a2ce0b..1a84666 100644
--- a/src/string_util.h
+++ b/src/string_util.h
@@ -6,7 +6,7 @@
 #include <utility>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/counter.h"
 #include "benchmark/export.h"
 #include "check.h"
 
diff --git a/src/sysinfo.cc b/src/sysinfo.cc
index 3977772..12a09cf 100644
--- a/src/sysinfo.cc
+++ b/src/sysinfo.cc
@@ -77,7 +77,9 @@
 #include <sstream>
 #include <utility>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/export.h"
+#include "benchmark/sysinfo.h"
+#include "benchmark/utils.h"
 #include "check.h"
 #include "cycleclock.h"
 #include "log.h"
diff --git a/src/thread_manager.h b/src/thread_manager.h
index a0ac37a..80252b6 100644
--- a/src/thread_manager.h
+++ b/src/thread_manager.h
@@ -3,7 +3,9 @@
 
 #include <atomic>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/counter.h"
+#include "benchmark/statistics.h"
+#include "benchmark/types.h"
 #include "mutex.h"
 
 namespace benchmark {
diff --git a/test/args_product_test.cc b/test/args_product_test.cc
index 63b8b71..5dbcc21 100644
--- a/test/args_product_test.cc
+++ b/test/args_product_test.cc
@@ -3,7 +3,10 @@
 #include <set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 
 class ArgsProductFixture : public ::benchmark::Fixture {
  public:
diff --git a/test/basic_test.cc b/test/basic_test.cc
index 068cd98..e1db1cb 100644
--- a/test/basic_test.cc
+++ b/test/basic_test.cc
@@ -1,5 +1,8 @@
 
-#include "benchmark/benchmark.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/types.h"
+#include "benchmark/utils.h"
 
 #define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192)
 
diff --git a/test/benchmark_gtest.cc b/test/benchmark_gtest.cc
index 0aa2552..09d7c80 100644
--- a/test/benchmark_gtest.cc
+++ b/test/benchmark_gtest.cc
@@ -3,7 +3,7 @@
 #include <vector>
 
 #include "../src/benchmark_register.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -136,7 +136,7 @@
 }
 
 TEST(AddCustomContext, Simple) {
-  std::map<std::string, std::string> *&global_context = GetGlobalContext();
+  std::map<std::string, std::string>*& global_context = GetGlobalContext();
   EXPECT_THAT(global_context, nullptr);
 
   AddCustomContext("foo", "bar");
@@ -151,7 +151,7 @@
 }
 
 TEST(AddCustomContext, DuplicateKey) {
-  std::map<std::string, std::string> *&global_context = GetGlobalContext();
+  std::map<std::string, std::string>*& global_context = GetGlobalContext();
   EXPECT_THAT(global_context, nullptr);
 
   AddCustomContext("foo", "bar");
diff --git a/test/benchmark_min_time_flag_iters_test.cc b/test/benchmark_min_time_flag_iters_test.cc
index dedcbe6..3866ac0 100644
--- a/test/benchmark_min_time_flag_iters_test.cc
+++ b/test/benchmark_min_time_flag_iters_test.cc
@@ -4,7 +4,10 @@
 #include <string>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 
 // Tests that we can specify the number of iterations with
 // --benchmark_min_time=<NUM>x.
diff --git a/test/benchmark_min_time_flag_time_test.cc b/test/benchmark_min_time_flag_time_test.cc
index bbc2cc3..2e8f52f 100644
--- a/test/benchmark_min_time_flag_time_test.cc
+++ b/test/benchmark_min_time_flag_time_test.cc
@@ -7,7 +7,10 @@
 #include <string>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 
 // Tests that we can specify the min time with
 // --benchmark_min_time=<NUM> (no suffix needed) OR
diff --git a/test/benchmark_name_gtest.cc b/test/benchmark_name_gtest.cc
index 0a6746d..34e97b0 100644
--- a/test/benchmark_name_gtest.cc
+++ b/test/benchmark_name_gtest.cc
@@ -1,4 +1,4 @@
-#include "benchmark/benchmark.h"
+#include "benchmark/reporter.h"
 #include "gtest/gtest.h"
 
 namespace {
diff --git a/test/benchmark_random_interleaving_gtest.cc b/test/benchmark_random_interleaving_gtest.cc
index 5f3a554..cb7f668 100644
--- a/test/benchmark_random_interleaving_gtest.cc
+++ b/test/benchmark_random_interleaving_gtest.cc
@@ -4,7 +4,10 @@
 
 #include "../src/commandlineflags.h"
 #include "../src/string_util.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
diff --git a/test/benchmark_setup_teardown_cb_types_gtest.cc b/test/benchmark_setup_teardown_cb_types_gtest.cc
index 2ed255d..716b722 100644
--- a/test/benchmark_setup_teardown_cb_types_gtest.cc
+++ b/test/benchmark_setup_teardown_cb_types_gtest.cc
@@ -1,4 +1,7 @@
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
+#include "benchmark/types.h"
 #include "gtest/gtest.h"
 
 using benchmark::Benchmark;
diff --git a/test/benchmark_setup_teardown_test.cc b/test/benchmark_setup_teardown_test.cc
index eb45a73..52d2761 100644
--- a/test/benchmark_setup_teardown_test.cc
+++ b/test/benchmark_setup_teardown_test.cc
@@ -4,7 +4,9 @@
 #include <cstring>
 #include <string>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 
 // Test that Setup() and Teardown() are called exactly once
 // for each benchmark run (single-threaded).
diff --git a/test/benchmark_test.cc b/test/benchmark_test.cc
index 49cbfba..b98fbdf 100644
--- a/test/benchmark_test.cc
+++ b/test/benchmark_test.cc
@@ -1,5 +1,3 @@
-#include "benchmark/benchmark.h"
-
 #include <assert.h>
 #include <math.h>
 #include <stdint.h>
@@ -19,6 +17,10 @@
 #include <utility>
 #include <vector>
 
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
+
 #if defined(__GNUC__)
 #define BENCHMARK_NOINLINE __attribute__((noinline))
 #else
diff --git a/test/clobber_memory_assembly_test.cc b/test/clobber_memory_assembly_test.cc
index 54e26cc..24e0666 100644
--- a/test/clobber_memory_assembly_test.cc
+++ b/test/clobber_memory_assembly_test.cc
@@ -1,4 +1,5 @@
-#include <benchmark/benchmark.h>
+#include "benchmark/macros.h"
+#include "benchmark/utils.h"
 
 #ifdef __clang__
 #pragma clang diagnostic ignored "-Wreturn-type"
diff --git a/test/complexity_test.cc b/test/complexity_test.cc
index 8cf17f4..64a7e72 100644
--- a/test/complexity_test.cc
+++ b/test/complexity_test.cc
@@ -4,7 +4,12 @@
 #include <cstdlib>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/statistics.h"
+#include "benchmark/types.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/cxx11_test.cc b/test/cxx11_test.cc
index db1a993..a2e8bc8 100644
--- a/test/cxx11_test.cc
+++ b/test/cxx11_test.cc
@@ -1,4 +1,4 @@
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
 
 #if defined(_MSC_VER)
 #if _MSVC_LANG != 201402L
diff --git a/test/diagnostics_test.cc b/test/diagnostics_test.cc
index e8d7d91..a79e49f 100644
--- a/test/diagnostics_test.cc
+++ b/test/diagnostics_test.cc
@@ -11,7 +11,10 @@
 #include <stdexcept>
 
 #include "../src/check.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 
 #if defined(__GNUC__) && !defined(__EXCEPTIONS)
 #define TEST_HAS_NO_EXCEPTIONS
diff --git a/test/display_aggregates_only_test.cc b/test/display_aggregates_only_test.cc
index bae9759..86f202f 100644
--- a/test/display_aggregates_only_test.cc
+++ b/test/display_aggregates_only_test.cc
@@ -3,7 +3,9 @@
 #include <cstdio>
 #include <string>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 #include "output_test.h"
 
 // Ok this test is super ugly. We want to check what happens with the file
diff --git a/test/donotoptimize_assembly_test.cc b/test/donotoptimize_assembly_test.cc
index 1f817e0..d7b3b54 100644
--- a/test/donotoptimize_assembly_test.cc
+++ b/test/donotoptimize_assembly_test.cc
@@ -1,4 +1,5 @@
-#include <benchmark/benchmark.h>
+#include "benchmark/macros.h"
+#include "benchmark/utils.h"
 
 #ifdef __clang__
 #pragma clang diagnostic ignored "-Wreturn-type"
diff --git a/test/donotoptimize_test.cc b/test/donotoptimize_test.cc
index 7571cf4..34b1ed6 100644
--- a/test/donotoptimize_test.cc
+++ b/test/donotoptimize_test.cc
@@ -1,6 +1,7 @@
 #include <cstdint>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/utils.h"
 
 namespace {
 #if defined(__GNUC__)
diff --git a/test/filter_test.cc b/test/filter_test.cc
index 8c150eb..bcbf2ff 100644
--- a/test/filter_test.cc
+++ b/test/filter_test.cc
@@ -8,7 +8,10 @@
 #include <sstream>
 #include <string>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 
 namespace {
 
diff --git a/test/fixture_test.cc b/test/fixture_test.cc
index d1093eb..8994dee 100644
--- a/test/fixture_test.cc
+++ b/test/fixture_test.cc
@@ -2,7 +2,9 @@
 #include <cassert>
 #include <memory>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 
 #define FIXTURE_BECHMARK_NAME MyFixture
 
diff --git a/test/internal_threading_test.cc b/test/internal_threading_test.cc
index c57bf44..4d1dd1b 100644
--- a/test/internal_threading_test.cc
+++ b/test/internal_threading_test.cc
@@ -5,7 +5,10 @@
 #include <thread>
 
 #include "../src/timers.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/counter.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/link_main_test.cc b/test/link_main_test.cc
index 41dbac9..538f807 100644
--- a/test/link_main_test.cc
+++ b/test/link_main_test.cc
@@ -1,4 +1,6 @@
-#include "benchmark/benchmark.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 
 namespace {
 void BM_empty(benchmark::State& state) {
diff --git a/test/locale_impermeability_test.cc b/test/locale_impermeability_test.cc
index e2dd6cf..0776fe6 100644
--- a/test/locale_impermeability_test.cc
+++ b/test/locale_impermeability_test.cc
@@ -3,7 +3,9 @@
 #include <cmath>
 #include <cstdlib>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/manual_threading_test.cc b/test/manual_threading_test.cc
index b3252ec..bac36bc 100644
--- a/test/manual_threading_test.cc
+++ b/test/manual_threading_test.cc
@@ -6,7 +6,10 @@
 #include <thread>
 
 #include "../src/timers.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/counter.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 
 namespace {
 
diff --git a/test/map_test.cc b/test/map_test.cc
index 018e12a..f4b41d2 100644
--- a/test/map_test.cc
+++ b/test/map_test.cc
@@ -1,7 +1,10 @@
 #include <cstdlib>
 #include <map>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 
 namespace {
 
diff --git a/test/memory_manager_test.cc b/test/memory_manager_test.cc
index 39b3216..36de9d4 100644
--- a/test/memory_manager_test.cc
+++ b/test/memory_manager_test.cc
@@ -1,6 +1,10 @@
 #include <memory>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/managers.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/memory_results_gtest.cc b/test/memory_results_gtest.cc
index 70a5a5a..f856fbf 100644
--- a/test/memory_results_gtest.cc
+++ b/test/memory_results_gtest.cc
@@ -1,6 +1,9 @@
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/managers.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 #include "gtest/gtest.h"
 
 namespace {
diff --git a/test/multiple_ranges_test.cc b/test/multiple_ranges_test.cc
index 987b69c..695b52a 100644
--- a/test/multiple_ranges_test.cc
+++ b/test/multiple_ranges_test.cc
@@ -3,7 +3,10 @@
 #include <set>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 
 namespace {
 class MultipleRangesFixture : public ::benchmark::Fixture {
diff --git a/test/options_test.cc b/test/options_test.cc
index 70e3e18..7ace933 100644
--- a/test/options_test.cc
+++ b/test/options_test.cc
@@ -1,7 +1,10 @@
 #include <chrono>
 #include <thread>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/types.h"
 
 #if defined(NDEBUG)
 #undef NDEBUG
diff --git a/test/output_test.h b/test/output_test.h
index 0fd557d..9337edc 100644
--- a/test/output_test.h
+++ b/test/output_test.h
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "../src/re.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
 
 #define CONCAT2(x, y) x##y
 #define CONCAT(x, y) CONCAT2(x, y)
diff --git a/test/overload_test.cc b/test/overload_test.cc
index d1fee9a..0a62b78 100644
--- a/test/overload_test.cc
+++ b/test/overload_test.cc
@@ -1,4 +1,6 @@
-#include "benchmark/benchmark.h"
+#include "benchmark/macros.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 
 namespace {
 // Simulate an overloaded function name.
diff --git a/test/perf_counters_test.cc b/test/perf_counters_test.cc
index a830b5e..d97fa37 100644
--- a/test/perf_counters_test.cc
+++ b/test/perf_counters_test.cc
@@ -3,7 +3,10 @@
 
 #include "../src/commandlineflags.h"
 #include "../src/perf_counters.h"
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 namespace benchmark {
diff --git a/test/profiler_manager_gtest.cc b/test/profiler_manager_gtest.cc
index 434e4ec..6e83e32 100644
--- a/test/profiler_manager_gtest.cc
+++ b/test/profiler_manager_gtest.cc
@@ -1,6 +1,9 @@
 #include <memory>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/managers.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 #include "gtest/gtest.h"
 
 namespace {
diff --git a/test/profiler_manager_iterations_test.cc b/test/profiler_manager_iterations_test.cc
index c4983eb..90b34a1 100644
--- a/test/profiler_manager_iterations_test.cc
+++ b/test/profiler_manager_iterations_test.cc
@@ -3,7 +3,11 @@
 #include <memory>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/managers.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 
 // Tests that we can specify the number of profiler iterations with
 // --benchmark_min_time=<NUM>x.
diff --git a/test/profiler_manager_test.cc b/test/profiler_manager_test.cc
index 5c4b14d..bd86d42 100644
--- a/test/profiler_manager_test.cc
+++ b/test/profiler_manager_test.cc
@@ -3,7 +3,11 @@
 #include <cassert>
 #include <memory>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/managers.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/register_benchmark_test.cc b/test/register_benchmark_test.cc
index 0ebd8f3..c662d49 100644
--- a/test/register_benchmark_test.cc
+++ b/test/register_benchmark_test.cc
@@ -4,7 +4,10 @@
 #include <vector>
 
 #include "../src/check.h"  // NOTE: check.h is for internal use only!
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 
 namespace {
 
diff --git a/test/repetitions_test.cc b/test/repetitions_test.cc
index 9116fa6..80216ab 100644
--- a/test/repetitions_test.cc
+++ b/test/repetitions_test.cc
@@ -1,5 +1,7 @@
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/report_aggregates_only_test.cc b/test/report_aggregates_only_test.cc
index 707d923..cb0ad09 100644
--- a/test/report_aggregates_only_test.cc
+++ b/test/report_aggregates_only_test.cc
@@ -3,7 +3,9 @@
 #include <cstdio>
 #include <string>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/reporter_output_test.cc b/test/reporter_output_test.cc
index 9940ab7..26d87de 100644
--- a/test/reporter_output_test.cc
+++ b/test/reporter_output_test.cc
@@ -1,6 +1,12 @@
 #undef NDEBUG
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/statistics.h"
+#include "benchmark/sysinfo.h"
+#include "benchmark/types.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/skip_with_error_test.cc b/test/skip_with_error_test.cc
index 4258959..d30c23e 100644
--- a/test/skip_with_error_test.cc
+++ b/test/skip_with_error_test.cc
@@ -4,7 +4,11 @@
 #include <vector>
 
 #include "../src/check.h"  // NOTE: check.h is for internal use only!
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 
 namespace {
 
diff --git a/test/spec_arg_test.cc b/test/spec_arg_test.cc
index 21275ef..393eca5 100644
--- a/test/spec_arg_test.cc
+++ b/test/spec_arg_test.cc
@@ -8,7 +8,10 @@
 #include <string>
 #include <vector>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/reporter.h"
+#include "benchmark/state.h"
 
 // Tests that we can override benchmark-spec value from FLAGS_benchmark_filter
 // with argument to RunSpecifiedBenchmarks(...).
diff --git a/test/spec_arg_verbosity_test.cc b/test/spec_arg_verbosity_test.cc
index 318784c..49aadd9 100644
--- a/test/spec_arg_verbosity_test.cc
+++ b/test/spec_arg_verbosity_test.cc
@@ -2,7 +2,9 @@
 
 #include <iostream>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 
 namespace {
 // Tests that the user specified verbosity level can be get.
diff --git a/test/state_assembly_test.cc b/test/state_assembly_test.cc
index e9ecfeb..5efceed 100644
--- a/test/state_assembly_test.cc
+++ b/test/state_assembly_test.cc
@@ -1,4 +1,5 @@
-#include <benchmark/benchmark.h>
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 
 #ifdef __clang__
 #pragma clang diagnostic ignored "-Wreturn-type"
diff --git a/test/templated_fixture_method_test.cc b/test/templated_fixture_method_test.cc
index 06fc7d8..3de726b 100644
--- a/test/templated_fixture_method_test.cc
+++ b/test/templated_fixture_method_test.cc
@@ -2,7 +2,9 @@
 #include <cassert>
 #include <memory>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 
 template <typename T>
 class MyFixture : public ::benchmark::Fixture {
diff --git a/test/templated_fixture_test.cc b/test/templated_fixture_test.cc
index af239c3..44108dd 100644
--- a/test/templated_fixture_test.cc
+++ b/test/templated_fixture_test.cc
@@ -2,7 +2,9 @@
 #include <cassert>
 #include <memory>
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 
 template <typename T>
 class MyFixture : public ::benchmark::Fixture {
diff --git a/test/time_unit_gtest.cc b/test/time_unit_gtest.cc
index 0da1109..1d4d2d0 100644
--- a/test/time_unit_gtest.cc
+++ b/test/time_unit_gtest.cc
@@ -1,4 +1,5 @@
-#include "../include/benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/state.h"
 #include "gtest/gtest.h"
 
 namespace benchmark {
diff --git a/test/user_counters_tabular_test.cc b/test/user_counters_tabular_test.cc
index 7db0e20..f173f1b 100644
--- a/test/user_counters_tabular_test.cc
+++ b/test/user_counters_tabular_test.cc
@@ -1,7 +1,11 @@
 
 #undef NDEBUG
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/counter.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/user_counters_test.cc b/test/user_counters_test.cc
index a8af087..9253d59 100644
--- a/test/user_counters_test.cc
+++ b/test/user_counters_test.cc
@@ -1,7 +1,11 @@
 
 #undef NDEBUG
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/counter.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 // ========================================================================= //
diff --git a/test/user_counters_thousands_test.cc b/test/user_counters_thousands_test.cc
index 0ef78d3..58170e9 100644
--- a/test/user_counters_thousands_test.cc
+++ b/test/user_counters_thousands_test.cc
@@ -1,7 +1,10 @@
 
 #undef NDEBUG
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/counter.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
 #include "output_test.h"
 
 namespace {
diff --git a/test/user_counters_threads_test.cc b/test/user_counters_threads_test.cc
index e2e5ade..9fd01a6 100644
--- a/test/user_counters_threads_test.cc
+++ b/test/user_counters_threads_test.cc
@@ -1,7 +1,10 @@
 
 #undef NDEBUG
 
-#include "benchmark/benchmark.h"
+#include "benchmark/benchmark_api.h"
+#include "benchmark/registration.h"
+#include "benchmark/state.h"
+#include "benchmark/utils.h"
 #include "output_test.h"
 
 // ========================================================================= //