// export COMPILE_FLAGS="-O3 -march=native -flto -ffast-math -fomit-frame-pointer -fcf-protection=none"
// export BM_INCLUDES="-I/usr/local/include -I$SYSTEM_PATH/include"
// export BM_LIBS="-lbenchmark -lpthread -lsystemc"
// g++-14 sc_time_bm.cpp $COMPILE_FLAGS $BM_INCLUDES -Lbenchmark/build/src $BM_LIBS -o sc_time_bm_gcc
// clang++-19 sc_time_bm.cpp $COMPILE_FLAGS $BM_INCLUDES -Lbenchmark/build/src $BM_LIBS -o sc_time_bm_clang

#include <benchmark/benchmark.h>
#include <systemc.h>


static void BM_constructor(benchmark::State& state) {
  for (auto _ : state) {
    volatile sc_time a = sc_time(23, SC_NS);
    volatile sc_time b = sc_time(24, SC_NS);
    volatile sc_time c = sc_time(25, SC_NS);
  }
}

BENCHMARK(BM_constructor);

static void BM_from_value(benchmark::State& state) {
  for (auto _ : state) {
    volatile sc_time a = sc_time::from_value(23);
    volatile sc_time b = sc_time::from_value(24);
    volatile sc_time c = sc_time::from_value(25);
  }
}

BENCHMARK(BM_from_value);

static void BM_copy_constructor(benchmark::State& state) {
  sc_time time(23, SC_NS);
  benchmark::DoNotOptimize(time);
  for (auto _ : state) {
    sc_time a(time);
    benchmark::DoNotOptimize(a);
    sc_time b(time);
    benchmark::DoNotOptimize(b);
    sc_time c(time);
    benchmark::DoNotOptimize(c);
  }
}

BENCHMARK(BM_copy_constructor);


int sc_main(int argc, char* argv[]) {
  sc_set_time_resolution(1.0, SC_NS);
  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;
}
