#pragma once

#include "./core/omp_config.h"
#include <random>

namespace utils{

    // Shared engine
    inline std::mt19937& rng() {
        static std::random_device rd;
        static std::mt19937 gen(rd());
        return gen;
    }

    // Integral overload
    template <
        typename T,
        typename std::enable_if<std::is_integral<T>::value, int>::type = 0
    >
    T random(T low, T high) {
        std::uniform_int_distribution<T> dist(low, high);
        return dist(rng());
    }

    // Floating-point overload
    template <
        typename T,
        typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0
    >
    T random(T low, T high) {
        std::uniform_real_distribution<T> dist(low, high);
        return dist(rng());
    }


} // end namespace utils

