#pragma once #include #include #include #if !defined(NDEBUG) && !defined(_WIN32) #include #endif namespace Util { enum LogLevel : u8 { Trace, Debug, Warn, Info, Error, Always }; #ifndef NDEBUG static constexpr auto globalLogLevel = Debug; #else static constexpr auto globalLogLevel = Info; #endif template void print(const std::format_string fmt, Args... args) { if (messageType >= globalLogLevel) { if (messageType <= Debug) { #ifndef NDEBUG std::println(fmt, std::forward(args)...); #endif } else { std::println(fmt, std::forward(args)...); } } } #define panic(fmt, ...) do { Util::print("[FATAL] " fmt __VA_OPT__(,) __VA_ARGS__); exit(-1); } while(0) #define error(fmt, ...) do { Util::print("[ERROR] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0) #define warn(fmt, ...) do { Util::print("[WARN] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0) #define info(fmt, ...) do { Util::print("[INFO] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0) #define debug(fmt, ...) do { Util::print("[DEBUG] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0) #define trace(fmt, ...) do { Util::print("[TRACE] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0) #define always(fmt, ...) do { Util::print(fmt __VA_OPT__(,) __VA_ARGS__); } while(0) } // namespace Util