From fafd3a4c22afbc25cf709beb68644e4ee9019621 Mon Sep 17 00:00:00 2001 From: Odysseas Georgoudis Date: Sat, 5 Oct 2024 02:00:07 +0100 Subject: [PATCH 01/10] Unify Json sinks and make them more flexible --- CMakeLists.txt | 3 +- docs/json_logging.rst | 6 +- examples/json_console_logging.cpp | 2 +- examples/json_file_logging.cpp | 2 +- examples/user_defined_types_logging.cpp | 1 + include/quill/sinks/JsonConsoleSink.h | 103 ---------------- .../sinks/{JsonFileSink.h => JsonSink.h} | 113 +++++++++++++----- .../JsonConsoleLoggingTest.cpp | 2 +- .../integration_tests/JsonFileLoggingTest.cpp | 2 +- .../JsonMultilineMetadataTest.cpp | 2 +- .../JsonVariedParamsLoggingTest.cpp | 2 +- 11 files changed, 93 insertions(+), 145 deletions(-) delete mode 100644 include/quill/sinks/JsonConsoleSink.h rename include/quill/sinks/{JsonFileSink.h => JsonSink.h} (60%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ad89de8..7d8897b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,8 +216,7 @@ set(HEADER_FILES include/quill/sinks/ConsoleSink.h include/quill/sinks/FileSink.h - include/quill/sinks/JsonConsoleSink.h - include/quill/sinks/JsonFileSink.h + include/quill/sinks/JsonSink.h include/quill/sinks/NullSink.h include/quill/sinks/RotatingFileSink.h include/quill/sinks/Sink.h diff --git a/docs/json_logging.rst b/docs/json_logging.rst index bef1d34e..8b003ad9 100644 --- a/docs/json_logging.rst +++ b/docs/json_logging.rst @@ -18,7 +18,7 @@ Logging Json to Console #include "quill/Frontend.h" #include "quill/LogMacros.h" #include "quill/Logger.h" - #include "quill/sinks/JsonConsoleSink.h" + #include "quill/sinks/JsonSink.h" #include int main() @@ -51,7 +51,7 @@ Logging Json to File #include "quill/Frontend.h" #include "quill/LogMacros.h" #include "quill/Logger.h" - #include "quill/sinks/JsonFileSink.h" + #include "quill/sinks/JsonSink.h" #include int main() @@ -92,7 +92,7 @@ Combining JSON and Standard Log Patterns #include "quill/LogMacros.h" #include "quill/Logger.h" #include "quill/sinks/ConsoleSink.h" - #include "quill/sinks/JsonFileSink.h" + #include "quill/sinks/JsonSink.h" #include int main() diff --git a/examples/json_console_logging.cpp b/examples/json_console_logging.cpp index 1cb0420f..78f1b025 100644 --- a/examples/json_console_logging.cpp +++ b/examples/json_console_logging.cpp @@ -2,7 +2,7 @@ #include "quill/Frontend.h" #include "quill/LogMacros.h" #include "quill/Logger.h" -#include "quill/sinks/JsonConsoleSink.h" +#include "quill/sinks/JsonSink.h" #include diff --git a/examples/json_file_logging.cpp b/examples/json_file_logging.cpp index bb804f60..d046e248 100644 --- a/examples/json_file_logging.cpp +++ b/examples/json_file_logging.cpp @@ -3,7 +3,7 @@ #include "quill/LogMacros.h" #include "quill/Logger.h" #include "quill/sinks/ConsoleSink.h" -#include "quill/sinks/JsonFileSink.h" +#include "quill/sinks/JsonSink.h" #include diff --git a/examples/user_defined_types_logging.cpp b/examples/user_defined_types_logging.cpp index 7c0b6173..8e450c96 100644 --- a/examples/user_defined_types_logging.cpp +++ b/examples/user_defined_types_logging.cpp @@ -2,6 +2,7 @@ #include "quill/Frontend.h" #include "quill/LogMacros.h" #include "quill/Logger.h" +#include "quill/bundled/fmt/ostream.h" #include "quill/sinks/ConsoleSink.h" #include diff --git a/include/quill/sinks/JsonConsoleSink.h b/include/quill/sinks/JsonConsoleSink.h deleted file mode 100644 index 9e115414..00000000 --- a/include/quill/sinks/JsonConsoleSink.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @page copyright - * Copyright(c) 2020-present, Odysseas Georgoudis & quill contributors. - * Distributed under the MIT License (http://opensource.org/licenses/MIT) - */ - -#pragma once - -#include "quill/bundled/fmt/base.h" -#include "quill/core/Attributes.h" -#include "quill/core/LogLevel.h" -#include "quill/core/MacroMetadata.h" -#include "quill/sinks/StreamSink.h" - -#include "quill/bundled/fmt/format.h" - -#include -#include -#include -#include -#include -#include - -QUILL_BEGIN_NAMESPACE - -class JsonConsoleSink : public StreamSink -{ -public: - JsonConsoleSink() : StreamSink("stdout", nullptr) {} - ~JsonConsoleSink() override = default; - - /** - * @brief Logs a formatted log message to the sink. - * @note Accessor for backend processing. - * @param log_metadata Pointer to the macro metadata. - * @param log_timestamp Timestamp of the log event. - * @param thread_id ID of the thread. - * @param thread_name Name of the thread. - * @param process_id Process Id - * @param logger_name Name of the logger. - * @param log_level Log level of the message. - * @param log_level_description Description of the log level. - * @param log_level_short_code Short code representing the log level. - * @param named_args Vector of key-value pairs of named args - */ - QUILL_ATTRIBUTE_HOT void write_log(MacroMetadata const* log_metadata, uint64_t log_timestamp, - std::string_view thread_id, std::string_view thread_name, - std::string const& process_id, std::string_view logger_name, LogLevel log_level, std::string_view log_level_description, - std::string_view log_level_short_code, - std::vector> const* named_args, - std::string_view, std::string_view) override - { - _json_message.clear(); - - char const* message_format; - - if (strchr(log_metadata->message_format(), '\n') != nullptr) - { - // The format string contains at least one new line and that would break the json message, it needs to be removed - _format = log_metadata->message_format(); - - for (size_t pos = 0; (pos = _format.find('\n', pos)) != std::string::npos; pos++) - { - _format.replace(pos, 1, " "); - } - - message_format = _format.data(); - } - else - { - message_format = log_metadata->message_format(); - } - - _json_message.append(fmtquill::format( - R"({{"timestamp":"{}","file_name":"{}","line":"{}","thread_id":"{}","logger":"{}","log_level":"{}","message":"{}")", - std::to_string(log_timestamp), log_metadata->file_name(), log_metadata->line(), thread_id, - logger_name, log_level_description, message_format)); - - if (named_args) - { - for (auto const& [key, value] : *named_args) - { - _json_message.append(std::string_view{",\""}); - _json_message.append(key); - _json_message.append(std::string_view{"\":\""}); - _json_message.append(value); - _json_message.append(std::string_view{"\""}); - } - } - - _json_message.append(std::string_view{"}\n"}); - - StreamSink::write_log(log_metadata, log_timestamp, thread_id, thread_name, process_id, logger_name, log_level, - log_level_description, log_level_short_code, named_args, std::string_view{}, - std::string_view{_json_message.data(), _json_message.size()}); - } - -private: - fmtquill::memory_buffer _json_message; - std::string _format; -}; - -QUILL_END_NAMESPACE \ No newline at end of file diff --git a/include/quill/sinks/JsonFileSink.h b/include/quill/sinks/JsonSink.h similarity index 60% rename from include/quill/sinks/JsonFileSink.h rename to include/quill/sinks/JsonSink.h index f5ecd688..e2cf9958 100644 --- a/include/quill/sinks/JsonFileSink.h +++ b/include/quill/sinks/JsonSink.h @@ -25,25 +25,18 @@ QUILL_BEGIN_NAMESPACE -/** - * The JsonFileSinkConfig class holds the configuration options for the JsonFileSink - */ -class JsonFileSinkConfig : public FileSinkConfig +namespace detail { -public: - JsonFileSinkConfig() = default; -}; - -class JsonFileSink : public FileSink +template +class JsonSink : public TBase { public: - JsonFileSink(fs::path const& filename, JsonFileSinkConfig const& config, - FileEventNotifier file_event_notifier = FileEventNotifier{}) - : FileSink(filename, static_cast(config), std::move(file_event_notifier)) - { - } + using base_type = TBase; - ~JsonFileSink() override = default; + /** Inherit base constructors **/ + using base_type::base_type; + + ~JsonSink() override = default; /** * @brief Logs a formatted log message to the sink. @@ -61,14 +54,13 @@ class JsonFileSink : public FileSink */ QUILL_ATTRIBUTE_HOT void write_log(MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id, std::string_view thread_name, - std::string const& process_id, std::string_view logger_name, LogLevel log_level, std::string_view log_level_description, + std::string const& process_id, std::string_view logger_name, + LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code, std::vector> const* named_args, - std::string_view, std::string_view) override + std::string_view log_message, std::string_view log_statement) override { - _json_message.clear(); - - char const* message_format; + char const* message_format = log_metadata->message_format(); if (strchr(log_metadata->message_format(), '\n') != nullptr) { @@ -80,18 +72,46 @@ class JsonFileSink : public FileSink _format.replace(pos, 1, " "); } + // we do not want newlines in the json message, use the modified message_format message_format = _format.data(); } - else - { - message_format = log_metadata->message_format(); - } + _json_message.clear(); + + generate_json_message(log_metadata, log_timestamp, thread_id, thread_name, process_id, + logger_name, log_level, log_level_description, log_level_short_code, + named_args, log_message, log_statement, message_format); + + _json_message.append(std::string_view{"}\n"}); + + StreamSink::write_log(log_metadata, log_timestamp, thread_id, thread_name, process_id, logger_name, log_level, + log_level_description, log_level_short_code, named_args, std::string_view{}, + std::string_view{_json_message.data(), _json_message.size()}); + } + + /** + * Generates a JSON-formatted log message. + * + * This function creates the default JSON structure for log messages, including the timestamp, + * file name, line number, thread information, logger name, log level, and message content. + * + * It is designed to be customizable by overriding in derived classes. Users can provide their own + * implementation to generate a log message in a custom format or to include additional fields. + */ + QUILL_ATTRIBUTE_HOT virtual void generate_json_message( + MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id, + std::string_view /** thread_name **/, std::string const& /** process_id **/, + std::string_view logger_name, LogLevel /** log_level **/, + std::string_view log_level_description, std::string_view /** log_level_short_code **/, + std::vector> const* named_args, + std::string_view /** log_message **/, std::string_view /** log_statement **/, char const* message_format) + { _json_message.append(fmtquill::format( R"({{"timestamp":"{}","file_name":"{}","line":"{}","thread_id":"{}","logger":"{}","log_level":"{}","message":"{}")", std::to_string(log_timestamp), log_metadata->file_name(), log_metadata->line(), thread_id, logger_name, log_level_description, message_format)); + // Add args as key-values if (named_args) { for (auto const& [key, value] : *named_args) @@ -103,17 +123,48 @@ class JsonFileSink : public FileSink _json_message.append(std::string_view{"\""}); } } - - _json_message.append(std::string_view{"}\n"}); - - StreamSink::write_log(log_metadata, log_timestamp, thread_id, thread_name, process_id, logger_name, log_level, - log_level_description, log_level_short_code, named_args, std::string_view{}, - std::string_view{_json_message.data(), _json_message.size()}); } -private: +protected: fmtquill::memory_buffer _json_message; + +private: std::string _format; }; +} // namespace detail + +/** + * The JsonFileSinkConfig class holds the configuration options for the JsonFileSink + */ +class JsonFileSinkConfig : public FileSinkConfig +{ +public: + JsonFileSinkConfig() = default; +}; + +/** + * JSON File Sink + */ +class JsonFileSink : public detail::JsonSink +{ +public: + JsonFileSink(fs::path const& filename, JsonFileSinkConfig const& config, + FileEventNotifier file_event_notifier = FileEventNotifier{}) + : detail::JsonSink(filename, static_cast(config), std::move(file_event_notifier)) + { + } + + ~JsonFileSink() override = default; +}; + +/** + * JSON Console Sink + */ +class JsonConsoleSink : public detail::JsonSink +{ +public: + JsonConsoleSink() : detail::JsonSink("stdout", nullptr) {} + ~JsonConsoleSink() override = default; +}; QUILL_END_NAMESPACE \ No newline at end of file diff --git a/test/integration_tests/JsonConsoleLoggingTest.cpp b/test/integration_tests/JsonConsoleLoggingTest.cpp index a42d86c5..a9e379ba 100644 --- a/test/integration_tests/JsonConsoleLoggingTest.cpp +++ b/test/integration_tests/JsonConsoleLoggingTest.cpp @@ -4,7 +4,7 @@ #include "quill/Backend.h" #include "quill/Frontend.h" #include "quill/LogMacros.h" -#include "quill/sinks/JsonConsoleSink.h" +#include "quill/sinks/JsonSink.h" #include "quill/bundled/fmt/format.h" diff --git a/test/integration_tests/JsonFileLoggingTest.cpp b/test/integration_tests/JsonFileLoggingTest.cpp index 13b4cc82..6a475141 100644 --- a/test/integration_tests/JsonFileLoggingTest.cpp +++ b/test/integration_tests/JsonFileLoggingTest.cpp @@ -6,7 +6,7 @@ #include "quill/LogMacros.h" #include "quill/bundled/fmt/format.h" #include "quill/bundled/fmt/ostream.h" -#include "quill/sinks/JsonFileSink.h" +#include "quill/sinks/JsonSink.h" #include #include diff --git a/test/integration_tests/JsonMultilineMetadataTest.cpp b/test/integration_tests/JsonMultilineMetadataTest.cpp index e2c705c7..6e6a8e44 100644 --- a/test/integration_tests/JsonMultilineMetadataTest.cpp +++ b/test/integration_tests/JsonMultilineMetadataTest.cpp @@ -5,7 +5,7 @@ #include "quill/Frontend.h" #include "quill/LogMacros.h" #include "quill/sinks/FileSink.h" -#include "quill/sinks/JsonFileSink.h" +#include "quill/sinks/JsonSink.h" #include #include diff --git a/test/integration_tests/JsonVariedParamsLoggingTest.cpp b/test/integration_tests/JsonVariedParamsLoggingTest.cpp index 4414eda3..d5a7f92f 100644 --- a/test/integration_tests/JsonVariedParamsLoggingTest.cpp +++ b/test/integration_tests/JsonVariedParamsLoggingTest.cpp @@ -5,7 +5,7 @@ #include "quill/Frontend.h" #include "quill/LogMacros.h" #include "quill/bundled/fmt/format.h" -#include "quill/sinks/JsonFileSink.h" +#include "quill/sinks/JsonSink.h" #include #include From e528cbd3c597ce796fe9f068fd3443d0df0fe5e8 Mon Sep 17 00:00:00 2001 From: Odysseas Georgoudis Date: Sat, 5 Oct 2024 02:03:02 +0100 Subject: [PATCH 02/10] Bump version --- CHANGELOG.md | 1 + MODULE.bazel | 2 +- docs/conf.py | 2 +- include/quill/Backend.h | 4 ++-- include/quill/core/Attributes.h | 2 +- meson.build | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4096378..06653692 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- [v8.0.0](#v800) - [v7.5.0](#v750) - [v7.4.0](#v740) - [v7.3.0](#v730) diff --git a/MODULE.bazel b/MODULE.bazel index ecae93a8..aad5ff3b 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,6 +1,6 @@ module( name = "quill", - version = "7.5.0", + version = "8.0.0", compatibility_level = 1, ) diff --git a/docs/conf.py b/docs/conf.py index 27b9bb0d..a97eabd3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -35,7 +35,7 @@ def configureDoxyfile(input_dir, output_dir): project = 'Quill' copyright = '2024, Odysseas Georgoudis' author = 'Odysseas Georgoudis' -release = 'v7.5.0' +release = 'v8.0.0' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/include/quill/Backend.h b/include/quill/Backend.h index e11a5446..e4e8c7ab 100644 --- a/include/quill/Backend.h +++ b/include/quill/Backend.h @@ -22,8 +22,8 @@ QUILL_BEGIN_NAMESPACE /** Version Info - When updating VersionMajor please also update the namespace in Attributes.h **/ -constexpr uint32_t VersionMajor{7}; -constexpr uint32_t VersionMinor{5}; +constexpr uint32_t VersionMajor{8}; +constexpr uint32_t VersionMinor{0}; constexpr uint32_t VersionPatch{0}; constexpr uint32_t Version{VersionMajor * 10000 + VersionMinor * 100 + VersionPatch}; diff --git a/include/quill/core/Attributes.h b/include/quill/core/Attributes.h index 760f5417..fb6d2595 100644 --- a/include/quill/core/Attributes.h +++ b/include/quill/core/Attributes.h @@ -10,7 +10,7 @@ #define QUILL_BEGIN_NAMESPACE \ namespace quill \ { \ - inline namespace v7 \ + inline namespace v8 \ { #define QUILL_END_NAMESPACE \ } \ diff --git a/meson.build b/meson.build index f715ecc8..c1e232c0 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('quill', 'cpp', version : '7.5.0', default_options : ['warning_level=3', 'cpp_std=c++17']) +project('quill', 'cpp', version : '8.0.0', default_options : ['warning_level=3', 'cpp_std=c++17']) inc_dirs = include_directories('include') From 3c348e47eaa0b5ef3893b50076b49463b6a389f2 Mon Sep 17 00:00:00 2001 From: Odysseas Georgoudis Date: Sat, 5 Oct 2024 02:11:32 +0100 Subject: [PATCH 03/10] Add custom json format example --- examples/CMakeLists.txt | 1 + examples/json_console_logging_custom_json.cpp | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 examples/json_console_logging_custom_json.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 62e5c74e..2a608940 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -23,6 +23,7 @@ set(EXAMPLE_TARGETS quill_example_user_defined_sink quill_example_tags_logging quill_example_json_console_logging + quill_example_json_console_logging_custom_json quill_example_csv_writing quill_example_json_file_logging quill_example_user_defined_types_logging diff --git a/examples/json_console_logging_custom_json.cpp b/examples/json_console_logging_custom_json.cpp new file mode 100644 index 00000000..824288a8 --- /dev/null +++ b/examples/json_console_logging_custom_json.cpp @@ -0,0 +1,65 @@ +#include "quill/Backend.h" +#include "quill/Frontend.h" +#include "quill/LogMacros.h" +#include "quill/Logger.h" +#include "quill/sinks/JsonSink.h" + +#include + +/** + * Overrides generate_json_message to use a custom json format + */ +class MyJsonConsoleSink : public quill::JsonConsoleSink +{ + void generate_json_message(quill::MacroMetadata const* /** log_metadata **/, uint64_t log_timestamp, + std::string_view /** thread_id **/, std::string_view /** thread_name **/, + std::string const& /** process_id **/, std::string_view /** logger_name **/, + quill::LogLevel /** log_level **/, std::string_view log_level_description, + std::string_view /** log_level_short_code **/, + std::vector> const* named_args, + std::string_view /** log_message **/, + std::string_view /** log_statement **/, char const* message_format) override + { + _json_message.append(fmtquill::format(R"({{"timestamp":"{}","log_level":"{}","message":"{}")", + std::to_string(log_timestamp), log_level_description, message_format)); + + // Add args as key-values + if (named_args) + { + for (auto const& [key, value] : *named_args) + { + _json_message.append(std::string_view{",\""}); + _json_message.append(key); + _json_message.append(std::string_view{"\":\""}); + _json_message.append(value); + _json_message.append(std::string_view{"\""}); + } + } + } +}; + +int main() +{ + // Start the backend thread + quill::BackendOptions backend_options; + quill::Backend::start(backend_options); + + // Frontend + + // Create a json sink + auto json_sink = quill::Frontend::create_or_get_sink("json_sink_1"); + + // When logging json, it is ideal to set the logging pattern to empty to avoid unnecessary message formatting. + quill::Logger* logger = quill::Frontend::create_or_get_logger( + "json_logger", std::move(json_sink), + quill::PatternFormatterOptions{"", "%H:%M:%S.%Qns", quill::Timezone::GmtTime}); + + int var_a = 123; + std::string var_b = "test"; + + // Log via the convenient LOGJ_ macros + LOGJ_INFO(logger, "A json message", var_a, var_b); + + // Or manually specify the desired names of each variable + LOG_INFO(logger, "A json message with {var_1} and {var_2}", var_a, var_b); +} From 379f74a1e5f83f0ec534e1bd24d3e930f6fad7fb Mon Sep 17 00:00:00 2001 From: Odysseas Georgoudis Date: Sat, 5 Oct 2024 02:14:18 +0100 Subject: [PATCH 04/10] remove deprecated functions --- include/quill/Backend.h | 15 --------------- include/quill/sinks/FileSink.h | 10 +--------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/include/quill/Backend.h b/include/quill/Backend.h index e4e8c7ab..4812e6f8 100644 --- a/include/quill/Backend.h +++ b/include/quill/Backend.h @@ -113,21 +113,6 @@ class Backend }); } - /***/ - template - [[deprecated( - "This function is deprecated and will be removed in the next version. Use " - "start(BackendOptions, SignalHandlerOptions) instead ")]] QUILL_ATTRIBUTE_COLD static void - start_with_signal_handler(BackendOptions const& options = BackendOptions{}, - QUILL_MAYBE_UNUSED std::initializer_list const& catchable_signals = - std::initializer_list{SIGTERM, SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV}, - uint32_t signal_handler_timeout_seconds = 20u, - std::string const& signal_handler_logger = {}) - { - SignalHandlerOptions sho{catchable_signals, signal_handler_timeout_seconds, signal_handler_logger}; - start(options, sho); - } - /** * Stops the backend thread. * @note thread-safe diff --git a/include/quill/sinks/FileSink.h b/include/quill/sinks/FileSink.h index 28d69921..1d358621 100644 --- a/include/quill/sinks/FileSink.h +++ b/include/quill/sinks/FileSink.h @@ -124,15 +124,7 @@ class FileSinkConfig * @param value True to perform fsync, false otherwise. */ QUILL_ATTRIBUTE_COLD void set_fsync_enabled(bool value) { _fsync_enabled = value; } - - [[deprecated( - "This function is deprecated and will be removed in the next version. Use set_fsync_enabled() " - "instead.")]] - QUILL_ATTRIBUTE_COLD void set_do_fsync(bool value) - { - _fsync_enabled = value; - } - + /** * @brief Sets the open mode for the file. * Valid options for the open mode are 'a' or 'w'. The default value is 'a'. From c4924d29ba03d456358dee1b47212e23c118e6cb Mon Sep 17 00:00:00 2001 From: Odysseas Georgoudis Date: Sat, 5 Oct 2024 12:49:15 +0100 Subject: [PATCH 05/10] format all files --- .../include/quill_wrapper/quill_wrapper.cpp | 2 +- examples/backend_tsc_clock.cpp | 2 +- examples/file_logging.cpp | 2 +- .../include/quill_wrapper/quill_wrapper.cpp | 2 +- examples/rotating_file_logging.cpp | 2 +- examples/shared_library/example_shared.cpp | 4 ++-- .../quill_wrapper_shared.cpp | 2 +- examples/signal_handler.cpp | 2 +- .../RotatingFileSinkWithFormatter.h | 11 +++++---- examples/user_defined_filter.cpp | 2 +- examples/user_defined_types_logging.cpp | 2 +- include/quill/CsvWriter.h | 4 ++-- include/quill/StringRef.h | 8 +++---- include/quill/backend/BackendOptions.h | 4 ++-- include/quill/backend/TransitEvent.h | 2 +- include/quill/core/LoggerBase.h | 4 +--- include/quill/core/SinkManager.h | 2 +- include/quill/core/ThreadContextManager.h | 8 +++---- include/quill/sinks/FileSink.h | 2 +- include/quill/sinks/NullSink.h | 3 ++- include/quill/sinks/RotatingFileSink.h | 3 ++- include/quill/sinks/StreamSink.h | 2 +- include/quill/std/Deque.h | 2 +- include/quill/std/FilesystemPath.h | 2 +- include/quill/std/ForwardList.h | 2 +- include/quill/std/List.h | 2 +- include/quill/std/Map.h | 2 +- include/quill/std/Optional.h | 2 +- include/quill/std/Pair.h | 2 +- include/quill/std/Set.h | 2 +- include/quill/std/Tuple.h | 2 +- include/quill/std/UnorderedMap.h | 2 +- include/quill/std/UnorderedSet.h | 7 +++--- include/quill/std/Vector.h | 2 +- .../BackendExceptionNotifierTest.cpp | 2 +- .../ConsoleSinkStderrMultipleFormatsTest.cpp | 3 ++- .../ConsoleSinkStdoutMultipleFormatsTest.cpp | 3 ++- .../JsonVariedParamsLoggingTest.cpp | 9 +++---- .../integration_tests/StdArrayLoggingTest.cpp | 2 +- .../StdVectorLoggingTest.cpp | 2 +- .../integration_tests/UserClockSourceTest.cpp | 6 ++--- .../UserDefinedTypeLoggingTest.cpp | 2 +- test/unit_tests/DynamicFormatArgStoreTest.cpp | 4 ++-- test/unit_tests/LogLevelTest.cpp | 24 +++++++++---------- test/unit_tests/LoggerTest.cpp | 4 ++-- 45 files changed, 84 insertions(+), 81 deletions(-) diff --git a/examples/advanced/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp b/examples/advanced/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp index 1fe08c44..b37569d0 100644 --- a/examples/advanced/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp +++ b/examples/advanced/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp @@ -17,6 +17,6 @@ void setup_quill(char const* log_file) quill::Frontend::create_or_get_logger( "root", std::move(console_sink), quill::PatternFormatterOptions{"%(time) [%(thread_id)] %(short_source_location:<28) " - "LOG_%(log_level:<9) %(logger:<12) %(message)", + "LOG_%(log_level:<9) %(logger:<12) %(message)", "%H:%M:%S.%Qns", quill::Timezone::GmtTime}); } \ No newline at end of file diff --git a/examples/backend_tsc_clock.cpp b/examples/backend_tsc_clock.cpp index e9b8827c..5cff4d42 100644 --- a/examples/backend_tsc_clock.cpp +++ b/examples/backend_tsc_clock.cpp @@ -52,7 +52,7 @@ int main() auto const tsc_start_seconds = std::chrono::duration_cast( quill::BackendTscClock::to_time_point(tsc_start).time_since_epoch()) .count(); - + auto const tsc_end_seconds = std::chrono::duration_cast( quill::BackendTscClock::to_time_point(tsc_end).time_since_epoch()) .count(); diff --git a/examples/file_logging.cpp b/examples/file_logging.cpp index 8545be02..4f1dcd0c 100644 --- a/examples/file_logging.cpp +++ b/examples/file_logging.cpp @@ -47,7 +47,7 @@ int main() quill::Logger* logger = quill::Frontend::create_or_get_logger( "root", std::move(file_sink), quill::PatternFormatterOptions{"%(time) [%(thread_id)] %(short_source_location:<28) " - "LOG_%(log_level:<9) %(logger:<12) %(message)", + "LOG_%(log_level:<9) %(logger:<12) %(message)", "%H:%M:%S.%Qns", quill::Timezone::GmtTime}); // set the log level of the logger to debug (default is info) diff --git a/examples/recommended_usage/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp b/examples/recommended_usage/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp index de8e9f21..8200b5de 100644 --- a/examples/recommended_usage/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp +++ b/examples/recommended_usage/quill_wrapper/include/quill_wrapper/quill_wrapper.cpp @@ -30,6 +30,6 @@ void setup_quill(char const* log_file) global_logger_a = quill::Frontend::create_or_get_logger( "root", std::move(file_sink), quill::PatternFormatterOptions{"%(time) [%(thread_id)] %(short_source_location:<28) " - "LOG_%(log_level:<9) %(logger:<12) %(message)", + "LOG_%(log_level:<9) %(logger:<12) %(message)", "%H:%M:%S.%Qns", quill::Timezone::GmtTime}); } \ No newline at end of file diff --git a/examples/rotating_file_logging.cpp b/examples/rotating_file_logging.cpp index 4fcbfbec..22707d28 100644 --- a/examples/rotating_file_logging.cpp +++ b/examples/rotating_file_logging.cpp @@ -34,7 +34,7 @@ int main() quill::Logger* logger = quill::Frontend::create_or_get_logger( "root", std::move(rotating_file_sink), quill::PatternFormatterOptions{"%(time) [%(thread_id)] %(short_source_location:<28) " - "LOG_%(log_level:<9) %(logger:<12) %(message)", + "LOG_%(log_level:<9) %(logger:<12) %(message)", "%H:%M:%S.%Qns", quill::Timezone::GmtTime}); for (int i = 0; i < 20; ++i) diff --git a/examples/shared_library/example_shared.cpp b/examples/shared_library/example_shared.cpp index bcca7c41..4b4cf4b6 100644 --- a/examples/shared_library/example_shared.cpp +++ b/examples/shared_library/example_shared.cpp @@ -24,8 +24,8 @@ int main() // Change the LogLevel to print everything global_logger_a->set_log_level(quill::LogLevel::TraceL3); - std::string s {"string"}; - std::string_view sv {"string_view"}; + std::string s{"string"}; + std::string_view sv{"string_view"}; LOG_TRACE_L3(global_logger_a, "This is a log trace l3 example {}", 1); LOG_TRACE_L2(global_logger_a, "This is a log trace l2 example {} {}", 2, 2.3); diff --git a/examples/shared_library/quill_wrapper_shared/include/quill_wrapper_shared/quill_wrapper_shared.cpp b/examples/shared_library/quill_wrapper_shared/include/quill_wrapper_shared/quill_wrapper_shared.cpp index 9030a8d5..e84816f4 100644 --- a/examples/shared_library/quill_wrapper_shared/include/quill_wrapper_shared/quill_wrapper_shared.cpp +++ b/examples/shared_library/quill_wrapper_shared/include/quill_wrapper_shared/quill_wrapper_shared.cpp @@ -20,6 +20,6 @@ void setup_quill() global_logger_a = quill::Frontend::create_or_get_logger( "root", std::move(console_sink), quill::PatternFormatterOptions{"%(time) [%(thread_id)] %(short_source_location:<28) " - "LOG_%(log_level:<9) %(logger:<12) %(message)", + "LOG_%(log_level:<9) %(logger:<12) %(message)", "%H:%M:%S.%Qns", quill::Timezone::GmtTime}); } \ No newline at end of file diff --git a/examples/signal_handler.cpp b/examples/signal_handler.cpp index 17688e84..7b282e21 100644 --- a/examples/signal_handler.cpp +++ b/examples/signal_handler.cpp @@ -76,7 +76,7 @@ int main() } // After 10 messages Crash - Uncomment any of the below : - + // illegal_instruction(logger); // cause_segfault(logger); }); diff --git a/examples/single_logger_multiple_sink_formats/RotatingFileSinkWithFormatter.h b/examples/single_logger_multiple_sink_formats/RotatingFileSinkWithFormatter.h index 81d52498..cc3ce640 100644 --- a/examples/single_logger_multiple_sink_formats/RotatingFileSinkWithFormatter.h +++ b/examples/single_logger_multiple_sink_formats/RotatingFileSinkWithFormatter.h @@ -19,18 +19,19 @@ class RotatingFileSinkWithFormatter : public quill::RotatingFileSink { } - void write_log(quill::MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id, - std::string_view thread_name, std::string const& process_id, - std::string_view logger_name, quill::LogLevel log_level, + void write_log(quill::MacroMetadata const* log_metadata, uint64_t log_timestamp, + std::string_view thread_id, std::string_view thread_name, + std::string const& process_id, std::string_view logger_name, quill::LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code, std::vector> const* named_args, - std::string_view log_message, std::string_view) override + std::string_view log_message, std::string_view) override { std::string_view const formatted_log_statement = _formatter.format(log_timestamp, thread_id, thread_name, process_id, logger_name, log_level_description, log_level_short_code, *log_metadata, named_args, log_message); - quill::RotatingFileSink::write_log(log_metadata, log_timestamp, thread_id, thread_name, process_id, logger_name, log_level, + quill::RotatingFileSink::write_log( + log_metadata, log_timestamp, thread_id, thread_name, process_id, logger_name, log_level, log_level_description, log_level_short_code, named_args, log_message, formatted_log_statement); } diff --git a/examples/user_defined_filter.cpp b/examples/user_defined_filter.cpp index 5b44686b..7fd374b0 100644 --- a/examples/user_defined_filter.cpp +++ b/examples/user_defined_filter.cpp @@ -19,7 +19,7 @@ class UserFilter : public quill::Filter { public: - UserFilter() : quill::Filter("filter_1"){}; + UserFilter() : quill::Filter("filter_1") {}; bool filter(quill::MacroMetadata const* /** log_metadata **/, uint64_t /** log_timestamp **/, std::string_view /** thread_id **/, std::string_view /** thread_name **/, diff --git a/examples/user_defined_types_logging.cpp b/examples/user_defined_types_logging.cpp index 8e450c96..013033b5 100644 --- a/examples/user_defined_types_logging.cpp +++ b/examples/user_defined_types_logging.cpp @@ -25,7 +25,7 @@ class User { public: User(std::string name, std::string surname, uint32_t age) - : name(std::move(name)), surname(std::move(surname)), age(age){}; + : name(std::move(name)), surname(std::move(surname)), age(age) {}; friend std::ostream& operator<<(std::ostream& os, User const& obj) { diff --git a/include/quill/CsvWriter.h b/include/quill/CsvWriter.h index a676f2f6..48d2775c 100644 --- a/include/quill/CsvWriter.h +++ b/include/quill/CsvWriter.h @@ -25,7 +25,7 @@ QUILL_BEGIN_NAMESPACE * and I/O operations are handled by the backend worker thread. * * @tparam TCsvSchema A user-defined struct specifying the CSV schema at compile-time. - * @tparam TFrontendOptions Custom frontend_t options if they are used application-wide. If no custom frontend_t options are used, then use quill::frontend_tOptions. + * @tparam TFrontendOptions Custom frontend options if they are used application-wide. If no custom frontend options are used, then use quill::FrontendOptions. * * The TCsvSchema struct should define the CSV header and format, for example: * @@ -42,7 +42,7 @@ class CsvWriter { public: using frontend_t = FrontendImpl; - + /** * Constructs a CsvWriter object that writes to a file. * diff --git a/include/quill/StringRef.h b/include/quill/StringRef.h index 35cad248..c280421a 100644 --- a/include/quill/StringRef.h +++ b/include/quill/StringRef.h @@ -32,10 +32,10 @@ namespace utility class StringRef { public: - explicit StringRef(std::string const& str) : _str_view(str){}; - explicit StringRef(std::string_view str) : _str_view(str){}; - explicit StringRef(char const* str) : _str_view(str, strlen(str)){}; - StringRef(char const* str, size_t size) : _str_view(str, size){}; + explicit StringRef(std::string const& str) : _str_view(str) {}; + explicit StringRef(std::string_view str) : _str_view(str) {}; + explicit StringRef(char const* str) : _str_view(str, strlen(str)) {}; + StringRef(char const* str, size_t size) : _str_view(str, size) {}; QUILL_NODISCARD std::string_view const& get_string_view() const noexcept { return _str_view; } diff --git a/include/quill/backend/BackendOptions.h b/include/quill/backend/BackendOptions.h index 6e330a28..cc23ca7d 100644 --- a/include/quill/backend/BackendOptions.h +++ b/include/quill/backend/BackendOptions.h @@ -205,8 +205,8 @@ struct BackendOptions * These names provide human-readable identifiers for each log level. */ std::array log_level_descriptions = { - "TRACE_L3", "TRACE_L2", "TRACE_L1", "DEBUG", "INFO", "NOTICE", "WARNING", - "ERROR", "CRITICAL", "BACKTRACE", "NONE", "DYNAMIC"}; + "TRACE_L3", "TRACE_L2", "TRACE_L1", "DEBUG", "INFO", "NOTICE", + "WARNING", "ERROR", "CRITICAL", "BACKTRACE", "NONE", "DYNAMIC"}; /** * @brief Short codes or identifiers for each log level. diff --git a/include/quill/backend/TransitEvent.h b/include/quill/backend/TransitEvent.h index bbe3923d..f66b3d58 100644 --- a/include/quill/backend/TransitEvent.h +++ b/include/quill/backend/TransitEvent.h @@ -32,7 +32,7 @@ class LoggerBase; struct TransitEvent { using FormatBuffer = fmtquill::basic_memory_buffer; - + /***/ TransitEvent() = default; diff --git a/include/quill/core/LoggerBase.h b/include/quill/core/LoggerBase.h index ccce6620..c841f5d7 100644 --- a/include/quill/core/LoggerBase.h +++ b/include/quill/core/LoggerBase.h @@ -72,9 +72,7 @@ class LoggerBase * Returns the user-defined clock source. * @return A pointer to the constant UserClockSource object. */ - QUILL_NODISCARD UserClockSource* get_user_clock_source() const noexcept { - return user_clock; - } + QUILL_NODISCARD UserClockSource* get_user_clock_source() const noexcept { return user_clock; } /** * Returns the type of clock source being used. diff --git a/include/quill/core/SinkManager.h b/include/quill/core/SinkManager.h index 87704c38..a1e1ee37 100644 --- a/include/quill/core/SinkManager.h +++ b/include/quill/core/SinkManager.h @@ -32,7 +32,7 @@ class SinkManager { explicit SinkInfo() = default; SinkInfo(std::string sid, std::weak_ptr sptr) - : sink_id(static_cast(sid)), sink_ptr(static_cast&&>(sptr)){}; + : sink_id(static_cast(sid)), sink_ptr(static_cast&&>(sptr)) {}; std::string sink_id; std::weak_ptr sink_ptr; diff --git a/include/quill/core/ThreadContextManager.h b/include/quill/core/ThreadContextManager.h index a44b6e5a..485f5232 100644 --- a/include/quill/core/ThreadContextManager.h +++ b/include/quill/core/ThreadContextManager.h @@ -186,9 +186,7 @@ class ThreadContext void mark_invalid() noexcept { _valid.store(false, std::memory_order_relaxed); } /***/ - QUILL_NODISCARD bool is_valid() const noexcept { - return _valid.load(std::memory_order_relaxed); - } + QUILL_NODISCARD bool is_valid() const noexcept { return _valid.load(std::memory_order_relaxed); } /***/ void increment_failure_counter() noexcept @@ -211,8 +209,8 @@ class ThreadContext SpscQueueUnion _spsc_queue_union; /**< queue for this thread */ SizeCacheVector _conditional_arg_size_cache; /**< cache for storing sizes needed for specific operations, such as when calling `strn` functions or when a loop is required e.g. caching the size of a type */ - std::string _thread_id = std::to_string(get_thread_id()); /**< cached thread pid */ - std::string _thread_name = get_thread_name(); /**< cached thread name */ + std::string _thread_id = std::to_string(get_thread_id()); /**< cached thread pid */ + std::string _thread_name = get_thread_name(); /**< cached thread name */ std::shared_ptr _transit_event_buffer; /**< backend thread buffer. this could be unique_ptr but it is shared_ptr because of the forward declaration */ QueueType _queue_type; std::atomic _valid{true}; /**< is this context valid, set by the frontend, read by the backend thread */ diff --git a/include/quill/sinks/FileSink.h b/include/quill/sinks/FileSink.h index 1d358621..79e4a6b0 100644 --- a/include/quill/sinks/FileSink.h +++ b/include/quill/sinks/FileSink.h @@ -124,7 +124,7 @@ class FileSinkConfig * @param value True to perform fsync, false otherwise. */ QUILL_ATTRIBUTE_COLD void set_fsync_enabled(bool value) { _fsync_enabled = value; } - + /** * @brief Sets the open mode for the file. * Valid options for the open mode are 'a' or 'w'. The default value is 'a'. diff --git a/include/quill/sinks/NullSink.h b/include/quill/sinks/NullSink.h index f2ed3af5..505ad6cd 100644 --- a/include/quill/sinks/NullSink.h +++ b/include/quill/sinks/NullSink.h @@ -26,7 +26,8 @@ class NullSink : public Sink public: QUILL_ATTRIBUTE_HOT void write_log(MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id, std::string_view thread_name, - std::string const& process_id, std::string_view logger_name, LogLevel log_level, std::string_view log_level_description, + std::string const& process_id, std::string_view logger_name, + LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code, std::vector> const* named_args, std::string_view log_message, std::string_view log_statement) override diff --git a/include/quill/sinks/RotatingFileSink.h b/include/quill/sinks/RotatingFileSink.h index bfd1e864..b268575b 100644 --- a/include/quill/sinks/RotatingFileSink.h +++ b/include/quill/sinks/RotatingFileSink.h @@ -309,7 +309,8 @@ class RotatingFileSink : public FileSink */ QUILL_ATTRIBUTE_HOT void write_log(MacroMetadata const* log_metadata, uint64_t log_timestamp, std::string_view thread_id, std::string_view thread_name, - std::string const& process_id, std::string_view logger_name, LogLevel log_level, std::string_view log_level_description, + std::string const& process_id, std::string_view logger_name, + LogLevel log_level, std::string_view log_level_description, std::string_view log_level_short_code, std::vector> const* named_args, std::string_view log_message, std::string_view log_statement) override diff --git a/include/quill/sinks/StreamSink.h b/include/quill/sinks/StreamSink.h index ef314023..664011c8 100644 --- a/include/quill/sinks/StreamSink.h +++ b/include/quill/sinks/StreamSink.h @@ -126,7 +126,7 @@ class StreamSink : public Sink */ QUILL_ATTRIBUTE_HOT void write_log(MacroMetadata const* /* log_metadata */, uint64_t /* log_timestamp */, std::string_view /* thread_id */, - std::string_view /* thread_name */, std::string const& /* process_id */, + std::string_view /* thread_name */, std::string const& /* process_id */, std::string_view /* logger_name */, LogLevel /* log_level */, std::string_view /* log_level_description */, std::string_view /* log_level_short_code */, diff --git a/include/quill/std/Deque.h b/include/quill/std/Deque.h index 7bff6388..c8cc123c 100644 --- a/include/quill/std/Deque.h +++ b/include/quill/std/Deque.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/FilesystemPath.h b/include/quill/std/FilesystemPath.h index 566611be..cf9fea42 100644 --- a/include/quill/std/FilesystemPath.h +++ b/include/quill/std/FilesystemPath.h @@ -12,8 +12,8 @@ #include "quill/core/Filesystem.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/std.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/std.h" #include #include diff --git a/include/quill/std/ForwardList.h b/include/quill/std/ForwardList.h index f270cc3c..3d16f19a 100644 --- a/include/quill/std/ForwardList.h +++ b/include/quill/std/ForwardList.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/List.h b/include/quill/std/List.h index 7cf86e90..cee1bae3 100644 --- a/include/quill/std/List.h +++ b/include/quill/std/List.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/Map.h b/include/quill/std/Map.h index 2f1e696a..9f5b77e4 100644 --- a/include/quill/std/Map.h +++ b/include/quill/std/Map.h @@ -12,8 +12,8 @@ #include "quill/core/InlinedVector.h" #include "quill/std/Pair.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/Optional.h b/include/quill/std/Optional.h index 92a32952..e0f4822d 100644 --- a/include/quill/std/Optional.h +++ b/include/quill/std/Optional.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/std.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/std.h" #include #include diff --git a/include/quill/std/Pair.h b/include/quill/std/Pair.h index 7ab40ed3..ade1e1c4 100644 --- a/include/quill/std/Pair.h +++ b/include/quill/std/Pair.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/Set.h b/include/quill/std/Set.h index 4e50683e..97cad995 100644 --- a/include/quill/std/Set.h +++ b/include/quill/std/Set.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/Tuple.h b/include/quill/std/Tuple.h index 27f2ca62..a71b6d25 100644 --- a/include/quill/std/Tuple.h +++ b/include/quill/std/Tuple.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/UnorderedMap.h b/include/quill/std/UnorderedMap.h index 69345100..e6ce5865 100644 --- a/include/quill/std/UnorderedMap.h +++ b/include/quill/std/UnorderedMap.h @@ -12,8 +12,8 @@ #include "quill/core/InlinedVector.h" #include "quill/std/Pair.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include diff --git a/include/quill/std/UnorderedSet.h b/include/quill/std/UnorderedSet.h index 120f1c63..8a783237 100644 --- a/include/quill/std/UnorderedSet.h +++ b/include/quill/std/UnorderedSet.h @@ -11,8 +11,8 @@ #include "quill/core/DynamicFormatArgStore.h" #include "quill/core/InlinedVector.h" -#include "quill/bundled/fmt/ranges.h" #include "quill/bundled/fmt/format.h" +#include "quill/bundled/fmt/ranges.h" #include #include @@ -24,8 +24,9 @@ QUILL_BEGIN_NAMESPACE template