#pragma once #include #include #include #include #include #include #include #include #include #include namespace version { namespace null { struct config { constexpr static auto build_id = std::uint64_t{}; constexpr static auto version_string = stdx::ct_string{""}; }; } // namespace null template inline auto config = null::config{}; } // namespace version namespace logging { namespace null { struct config { struct { template constexpr auto log(auto &&...) const noexcept -> void {} } logger; }; } // namespace null template inline auto config = null::config{}; struct default_flavor_t; template ALWAYS_INLINE constexpr static auto get_config() -> auto & { if constexpr (std::same_as) { return config; } else { return config; } } template ALWAYS_INLINE static auto log(TArgs &&...args) -> void { auto &cfg = get_config(); cfg.logger.template log(std::forward(args)...); } } // namespace logging // NOLINTBEGIN(cppcoreguidelines-macro-usage) #define CIB_LOG(FLAVOR, MSG, ...) \ logging::log( \ __FILE__, __LINE__, sc::format(MSG##_sc __VA_OPT__(, ) __VA_ARGS__)) #define CIB_LOG_WITH_LEVEL(LEVEL, ...) \ do { \ CIB_LOG_ENV(logging::get_level, LEVEL); \ CIB_LOG(logging::default_flavor_t __VA_OPT__(, ) __VA_ARGS__); \ } while (false) #define CIB_TRACE(...) \ CIB_LOG_WITH_LEVEL(logging::level::TRACE __VA_OPT__(, ) __VA_ARGS__) #define CIB_INFO(...) \ CIB_LOG_WITH_LEVEL(logging::level::INFO __VA_OPT__(, ) __VA_ARGS__) #define CIB_WARN(...) \ CIB_LOG_WITH_LEVEL(logging::level::WARN __VA_OPT__(, ) __VA_ARGS__) #define CIB_ERROR(...) \ CIB_LOG_WITH_LEVEL(logging::level::ERROR __VA_OPT__(, ) __VA_ARGS__) #define CIB_FATAL(MSG, ...) \ [](auto &&str) { \ CIB_LOG_ENV(logging::get_level, logging::level::FATAL); \ logging::log(__FILE__, \ __LINE__, str); \ FWD(str).apply([](S s, Args... args) { \ constexpr auto cts = stdx::ct_string_from_type(s); \ stdx::panic(args...); \ }); \ }(sc::format(MSG##_sc __VA_OPT__(, ) __VA_ARGS__)) #define CIB_ASSERT(expr) \ ((expr) ? void(0) : CIB_FATAL("Assertion failure: " #expr)) namespace logging { template ALWAYS_INLINE static auto log_version() -> void { auto &l_cfg = get_config(); auto &v_cfg = ::version::config; if constexpr (requires { l_cfg.logger.template log_build(); }) { l_cfg.logger.template log_build(); } else { CIB_LOG_ENV(logging::get_level, logging::level::MAX); l_cfg.logger.template log( "", 0, sc::format("Version: {} ({})"_sc, sc::uint_, stdx::ct_string_to_type())); } } } // namespace logging #define CIB_LOG_V(FLAVOR) logging::log_version() #define CIB_LOG_VERSION() CIB_LOG_V(logging::default_flavor_t) // NOLINTEND(cppcoreguidelines-macro-usage)