diff --git a/include/dwarfs/detail/logging_class_factory.h b/include/dwarfs/detail/logging_class_factory.h
new file mode 100644
index 00000000..ab065fab
--- /dev/null
+++ b/include/dwarfs/detail/logging_class_factory.h
@@ -0,0 +1,94 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/**
+ * \author Marcus Holland-Moritz (github@mhxnet.de)
+ * \copyright Copyright (c) Marcus Holland-Moritz
+ *
+ * This file is part of dwarfs.
+ *
+ * dwarfs is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dwarfs is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with dwarfs. If not, see .
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace dwarfs {
+
+class logger;
+
+namespace detail {
+
+template
+struct unique_ptr_policy {
+ using return_type = std::unique_ptr;
+
+ template
+ static return_type create(Args&&... args) {
+ return std::make_unique(std::forward(args)...);
+ }
+};
+
+template
+struct shared_ptr_policy {
+ using return_type = std::shared_ptr;
+
+ template
+ static return_type create(Args&&... args) {
+ return std::make_shared(std::forward(args)...);
+ }
+};
+
+class logging_class_factory {
+ public:
+ template class T, class CreatePolicy,
+ class LoggerPolicyList, class... Args>
+ static typename CreatePolicy::return_type
+ create(logger& lgr, Args&&... args) {
+ return create_unwrap(
+ lgr, std::type_identity{},
+ std::forward(args)...);
+ }
+
+ private:
+ template class T, class CreatePolicy,
+ class... LoggerPolicies, class... Args>
+ static typename CreatePolicy::return_type
+ create_unwrap(logger& lgr, std::type_identity>,
+ Args&&... args) {
+ return create_impl(
+ lgr, std::forward(args)...);
+ }
+
+ template class T, class CreatePolicy, class LoggerPolicy,
+ class... Rest, class... Args>
+ static typename CreatePolicy::return_type
+ create_impl(logger& lgr, Args&&... args) {
+ if (is_policy_name(lgr, LoggerPolicy::name())) {
+ return CreatePolicy::template create>(
+ lgr, std::forward(args)...);
+ } else if constexpr (sizeof...(Rest) > 0) {
+ return create_impl(lgr,
+ std::forward(args)...);
+ }
+ on_policy_not_found(lgr);
+ }
+
+ static bool is_policy_name(logger const& lgr, std::string_view name);
+ [[noreturn]] static void on_policy_not_found(logger const& lgr);
+};
+
+} // namespace detail
+} // namespace dwarfs
diff --git a/include/dwarfs/logger.h b/include/dwarfs/logger.h
index a135b1b8..c602e43c 100644
--- a/include/dwarfs/logger.h
+++ b/include/dwarfs/logger.h
@@ -39,7 +39,7 @@
#include
-#include
+#include
#include
namespace dwarfs {
@@ -65,26 +65,22 @@ class logger {
virtual void write(level_type level, const std::string& output,
char const* file, int line) = 0;
- const std::string& policy_name() const { return policy_name_; }
-
- template
- void set_policy() // TODO: construction time arg?
- {
- policy_name_ = Policy::name();
- }
-
- void set_policy_name(const std::string& name) // TODO: construction time arg?
- {
- policy_name_ = name;
- }
+ std::string_view policy_name() const { return policy_name_; }
static level_type parse_level(std::string_view level);
static std::string_view level_name(level_type level);
static std::string all_level_names();
+ protected:
+ template
+ void set_policy() // TODO: construction time arg?
+ {
+ policy_name_ = Policy::name();
+ }
+
private:
- std::string policy_name_; // TODO: const?
+ std::string_view policy_name_;
};
std::ostream& operator<<(std::ostream& os, logger::level_type const& optval);
@@ -395,82 +391,30 @@ class log_proxy {
class prod_logger_policy : public MinimumLogLevelPolicy {
public:
- static std::string name() { return "prod"; }
+ static std::string_view name() { return "prod"; }
};
class debug_logger_policy : public MinimumLogLevelPolicy {
public:
- static std::string name() { return "debug"; }
+ static std::string_view name() { return "debug"; }
};
using logger_policies = std::tuple;
-template
-struct unique_ptr_policy {
- using return_type = std::unique_ptr;
-
- template
- static return_type create(Args&&... args) {
- return std::make_unique(std::forward(args)...);
- }
-};
-
-template
-struct shared_ptr_policy {
- using return_type = std::shared_ptr;
-
- template
- static return_type create(Args&&... args) {
- return std::make_shared(std::forward(args)...);
- }
-};
-
-template class T, class CreatePolicy, class LoggerPolicyList,
- size_t N>
-struct logging_class_factory {
- template
- static typename CreatePolicy::return_type
- create(logger& lgr, Args&&... args) {
- if (std::tuple_element::type::name() ==
- lgr.policy_name()) {
- using obj_type =
- T::type>;
- return CreatePolicy::template create(
- lgr, std::forward(args)...);
- }
-
- return logging_class_factory::create(lgr,
- std::forward(args)...);
- }
-};
-
-template class T, class CreatePolicy, class LoggerPolicyList>
-struct logging_class_factory {
- template
- static typename CreatePolicy::return_type create(logger& lgr, Args&&...) {
- DWARFS_THROW(runtime_error, "no such logger policy: " + lgr.policy_name());
- }
-};
-
template class T, class LoggerPolicyList,
class... Args>
std::unique_ptr make_unique_logging_object(logger& lgr, Args&&... args) {
- return logging_class_factory<
- T, unique_ptr_policy, LoggerPolicyList,
- std::tuple_size::value>::create(lgr,
- std::forward(
- args)...);
+ return detail::logging_class_factory::create<
+ T, detail::unique_ptr_policy, LoggerPolicyList>(
+ lgr, std::forward(args)...);
}
template class T, class LoggerPolicyList,
class... Args>
std::shared_ptr make_shared_logging_object(logger& lgr, Args&&... args) {
- return logging_class_factory<
- T, shared_ptr_policy, LoggerPolicyList,
- std::tuple_size::value>::create(lgr,
- std::forward(
- args)...);
+ return detail::logging_class_factory::create<
+ T, detail::shared_ptr_policy, LoggerPolicyList>(
+ lgr, std::forward(args)...);
}
std::string get_logger_context(char const* path, int line);
diff --git a/src/logger.cpp b/src/logger.cpp
index 18f1dd89..6b536587 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -38,6 +38,7 @@
#include
#include
+#include
#include
#include
#include
@@ -291,6 +292,20 @@ void stream_logger::set_threshold(level_type threshold) {
}
}
+namespace detail {
+
+bool logging_class_factory::is_policy_name(logger const& lgr,
+ std::string_view name) {
+ return lgr.policy_name() == name;
+}
+
+void logging_class_factory::on_policy_not_found(logger const& lgr) {
+ DWARFS_THROW(runtime_error,
+ fmt::format("no such logger policy: {}", lgr.policy_name()));
+}
+
+} // namespace detail
+
std::string get_logger_context(char const* path, int line) {
return fmt::format("[{0}:{1}] ", basename(path), line);
}