#pragma once #include namespace geode::utils { template struct is_chrono_duration { static constexpr bool value = false; }; template struct is_chrono_duration> { static constexpr bool value = true; }; template class Timer { public: using clock_point = std::chrono::time_point; private: clock_point m_start; public: Timer() { m_start = Clock::now(); } void reset() { m_start = Clock::now(); } clock_point time() const { return m_start; } template int64_t elapsed() const { static_assert(is_chrono_duration::value, "Duration must be a std::chrono::duration"); auto end = Clock::now(); return std::chrono::duration_cast(end - m_start).count(); } template std::string elapsedAsString() const { static_assert(is_chrono_duration::value, "Duration must be a std::chrono::duration"); if constexpr (std::is_same::value) { return std::to_string(this->elapsed()) + "ms"; } else if constexpr (std::is_same::value) { return std::to_string(this->elapsed()) + "us"; } else if constexpr (std::is_same::value) { return std::to_string(this->elapsed()) + "ns"; } else { // static_assert(!std::is_same_v, "Unsupported duration type"); } } }; template< typename Duration = std::chrono::milliseconds, class Clock = std::chrono::high_resolution_clock > struct LogPerformance { std::ostream& m_output; std::string m_msg; Timer m_timer; LogPerformance( std::string const& msg = "", std::ostream& out = std::cout ) : m_msg(msg), m_output(out) { m_timer = Timer(); }; ~LogPerformance() { m_output << "Running \"" << m_msg << "\" took " << m_timer.template elapsedAsString() << std::endl; } }; }