diff --git a/Alloy.toml b/Alloy.toml index 6b597aa..76f0779 100644 --- a/Alloy.toml +++ b/Alloy.toml @@ -6,7 +6,7 @@ version = "0.1.0" [lib] name = "libjournal" -cc-flags = ["-DJOURNAL_GLOG_COMPAT"] +cc-flags = ["-DJOURNAL_GLOG_COMPAT", "-fno-threadsafe-statics"] [[bin]] name = "journal" diff --git a/include/journal.hpp b/include/journal.hpp index bcf8404..314041c 100644 --- a/include/journal.hpp +++ b/include/journal.hpp @@ -1,5 +1,6 @@ #pragma once +#include "journal.hpp" #include #include #include @@ -75,9 +76,9 @@ struct Formatter { } // namespace formatter template -inline constexpr auto log(const LogVerbosity &verbosity, std::string_view fmt, - Args... args, const detail::source_location source) - -> void { +inline constexpr auto log(const LogVerbosity &verbosity, + const detail::source_location &source, + std::string_view fmt, Args... args) -> void { const auto msg = std::vformat(fmt, std::make_format_args(args...)); log_internal(verbosity, source, msg); } @@ -106,6 +107,10 @@ auto add_sink(std::shared_ptr stream, const LogVerbosity &min = LogVerbosity::Trace, const LogVerbosity &max = LogVerbosity::Error) -> void; +template inline constexpr auto ptr(T *p) -> const void * { + return reinterpret_cast(p); +} + /// JOURNAL_NONE: undefines all logs /// JOURNAL_ALL: defines all logs, on by default /// JOURNAL_NOT_ALL: does not define any logs by default even it JOURNAL_ALL is @@ -127,79 +132,118 @@ auto add_sink(std::shared_ptr stream, #endif #ifdef JOURNAL_TRACE -template -inline constexpr auto -trace(std::string_view fmt, Args... args, - const detail::source_location source = detail::source_location::current()) - -> void { - detail::log(detail::LogVerbosity::Trace, fmt, args..., source); -} +template struct trace { + trace(std::string_view fmt, Ts &&...args, + const detail::source_location &source = + detail::source_location::current()) { + detail::log(detail::LogVerbosity::Trace, source, fmt, + std::forward(args)...); + } +}; + +template trace(std::string_view, Ts &&...) -> trace; #else template inline constexpr auto trace(std::string_view fmt, Args... args) -> void {} #endif #ifdef JOURNAL_DEBUG -template -inline constexpr auto -debug(std::string_view fmt, Args... args, - const detail::source_location source = detail::source_location::current()) - -> void { - detail::log(detail::LogVerbosity::Debug, fmt, args..., source); -} +template struct debug { + debug(std::string_view fmt, Ts &&...args, + const detail::source_location &source = + detail::source_location::current()) { + detail::log(detail::LogVerbosity::Debug, source, fmt, + std::forward(args)...); + } +}; + +template debug(std::string_view, Ts &&...) -> debug; #else template inline constexpr auto debug(std::string_view fmt, Args... args) -> void {} #endif #ifdef JOURNAL_INFO -template -inline constexpr auto -info(std::string_view fmt, Args... args, - const detail::source_location source = detail::source_location::current()) - -> void { - detail::log(detail::LogVerbosity::Info, fmt, args..., source); -} +template struct info { + info(std::string_view fmt, Ts &&...args, + const detail::source_location &source = + detail::source_location::current()) { + detail::log(detail::LogVerbosity::Info, source, fmt, + std::forward(args)...); + } +}; + + template + info(std::string_view, Ts &&...) -> info; #else template inline constexpr auto info(std::string_view fmt, Args... args) -> void {} #endif #ifdef JOURNAL_WARN -template -inline constexpr auto -warn(std::string_view fmt, Args... args, - const detail::source_location source = detail::source_location::current()) - -> void { - detail::log(detail::LogVerbosity::Warn, fmt, args..., source); -} +template struct warn { + warn(std::string_view fmt, Ts &&...args, + const detail::source_location &source = + detail::source_location::current()) { + detail::log(detail::LogVerbosity::Warn, source, fmt, + std::forward(args)...); + } +}; + +template warn(std::string_view, Ts &&...) -> warn; #else template inline constexpr auto warn(std::string_view fmt, Args... args) -> void {} #endif #ifdef JOURNAL_ERROR -template -inline constexpr auto -error(std::string_view fmt, Args... args, - const detail::source_location source = detail::source_location::current()) - -> void { - detail::log(detail::LogVerbosity::Error, fmt, args..., source); -} +template struct error { + error(std::string_view fmt, Ts &&...args, + const detail::source_location &source = + detail::source_location::current()) { + detail::log(detail::LogVerbosity::Error, source, fmt, + std::forward(args)...); + } +}; + +template error(std::string_view, Ts &&...) -> error; #else template inline constexpr auto error(std::string_view fmt, Args... args) -> void {} #endif +} // namespace journal + /// JOURNAL_GLOG_COMPAT: enables LOG_F macro format which GLOG and Loguru use /// for compatibility, on by default #if defined(JOURNAL_GLOG_COMPAT) -#define LOG_F_TRACE(...) trace(__VA_ARGS__) -#define LOG_F_DEBUG(...) debug(__VA_ARGS__) -#define LOG_F_INFO(...) info(__VA_ARGS__) -#define LOG_F_WARN(...) warn(__VA_ARGS__) -#define LOG_F_ERROR(...) error(__VA_ARGS__) -#define LOG_F(V, ...) LOG_F_##V(__VA_ARGS__) -#endif +namespace journal { +constexpr auto JournalGLogVerbosity_ERROR = detail::LogVerbosity::Error; +constexpr auto JournalGLogVerbosity_WARNING = detail::LogVerbosity::Warn; +constexpr auto JournalGLogVerbosity_WARN = detail::LogVerbosity::Warn; +constexpr auto JournalGLogVerbosity_INFO = detail::LogVerbosity::Info; +constexpr auto JournalGLogVerbosity_DEBUG = detail::LogVerbosity::Debug; +constexpr auto JournalGLogVerbosity_TRACE = detail::LogVerbosity::Trace; -} // namespace journal \ No newline at end of file +struct GLogCompatHelper { + const detail::source_location source; + const detail::LogVerbosity verbosity; + + consteval GLogCompatHelper(const detail::LogVerbosity &verbosity, + const detail::source_location &source = + detail::source_location::current()) noexcept + : source(source), verbosity(verbosity) {} + + template + auto log(std::string_view fmt, Ts &&...args) const -> void { + detail::log(verbosity, source, fmt, std::forward(args)...); + } +}; + +} // namespace journal + +#define LOG_F(V, ...) \ + journal::GLogCompatHelper(journal::JournalGLogVerbosity_##V, \ + journal::detail::source_location::current()) \ + .log(__VA_ARGS__); +#endif \ No newline at end of file diff --git a/src/journal.cc b/src/journal.cc index e886c58..3497a43 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -257,6 +257,11 @@ struct FileSink : public OStreamSink { const Verbosity &max = LogVerbosity::Error) : OStreamSink(std::make_shared(file_path, open_mode), min, max) {} + + FileSink(const std::shared_ptr &file, + const Verbosity &min = LogVerbosity::Trace, + const Verbosity &max = LogVerbosity::Error) + : OStreamSink(file, min, max) {} }; } // namespace sinks @@ -344,7 +349,10 @@ auto add_file(const std::string &file_name, std::ios::ios_base::openmode open_mode = std::ios::ios_base::app, const Verbosity &min = LogVerbosity::Trace, const Verbosity &max = LogVerbosity::Error) -> void { - add_sink(std::make_unique(file_name, open_mode, min, max)); + auto file = std::make_shared(file_name, open_mode); + if (file->is_open() && !(file->bad() || file->fail())) { + add_sink(std::make_unique(file, min, max)); + } } auto add_sink(std::unique_ptr &&sink) -> void { diff --git a/src/main.cc b/src/main.cc index 112a345..f5fc260 100644 --- a/src/main.cc +++ b/src/main.cc @@ -14,6 +14,9 @@ int main(int argc, const char* argv[]) { journal::info("some info!"); journal::error("something went wrong!"); journal::warn("something went slightly wrong!"); + LOG_F(INFO, "test "); + LOG_F(INFO, "test {}", 1.3f); + LOG_F(INFO, "test {} {} {}", 1.3f, true, 'C'); std::cin.get(); std::cout << "stream content: \n" << stream->view() << "\n"; journal::trace("just some very verbose stuff here");