// El medidor de la semana 3.
#ifndef BENCH_H
#define BENCH_H

#include <algorithm>
#include <chrono>
#include <cstddef>
#include <vector>

// Corre fn `reps` veces y devuelve la mediana en segundos.
template <typename Fn>
double median_seconds(int reps, Fn fn) {
    std::vector<double> times;
    for (int i = 0; i < reps; i++) {
        auto start = std::chrono::steady_clock::now();
        fn();
        auto stop = std::chrono::steady_clock::now();
        times.push_back(std::chrono::duration<double>(stop - start).count());
    }
    std::sort(times.begin(), times.end());
    std::size_t middle = times.size() / 2;
    if (times.size() % 2 == 1) {
        return times[middle];
    }
    return (times[middle - 1] + times[middle]) / 2;
}

// Evita que el compilador borre un cálculo cuyo resultado no se usa.
template <typename T>
void keep(const T& value) {
    asm volatile("" : : "m"(value) : "memory");
}

#endif
