numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
log_sink_factory_table.h
Go to the documentation of this file.
1/*
2 * Copyright 2022 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <memory>
23#include <optional>
24#include <stdexcept>
25#include <string>
26#include <string_view>
27#include <unordered_map>
28#include <unordered_set>
29#include <utility>
30
31#include <fmt/format.h>
32
37
39
41constexpr auto default_log_sink_name = std::string_view("default");
42
49public:
52 append(std::string{default_log_sink_name},
53 std::make_shared<default_log_sink_factory>());
54 }
55
62 void append(const std::string& name,
63 const std::shared_ptr<log_sink_factory_base>& sink_factory) {
64 if (!caches_.try_emplace(name, sink_factory).second) {
65 throw invalid_argument(fmt::format(
66 "Duplicate configurations of a log sink {}.", name));
67 }
68 }
69
76 [[nodiscard]] auto get(const std::string& name) -> sinks::log_sink {
78 const auto iter = caches_.find(name);
79 if (iter == caches_.end()) {
80 throw std::invalid_argument(
81 fmt::format("Log sink {} not found.", name));
82 }
83 auto sink = iter->second.get(*this);
85 return sink;
86 }
87
88private:
91 public:
97 explicit cached_log_sink(std::shared_ptr<log_sink_factory_base> factory)
98 : factory_(std::move(factory)) {}
99
106 [[nodiscard]] auto get(log_sink_factory_table& sinks)
107 -> sinks::log_sink {
108 if (!sink_) {
109 sink_ = factory_->create(sinks);
110 }
111 return *sink_;
112 }
113
114 private:
116 std::shared_ptr<log_sink_factory_base> factory_;
117
119 std::optional<sinks::log_sink> sink_;
120 };
121
128 void check_sink_reference_loop(std::string name) {
129 if (!currently_creating_sink_names_.insert(std::move(name)).second) {
130 throw invalid_argument(
131 fmt::format("Loop of references of log sinks in configurations "
132 "detected for log sink {}.",
133 name));
134 }
135 }
136
143 void pop_created_log_sink_name(const std::string& name) {
145 }
146
148 std::unordered_map<std::string, cached_log_sink> caches_{};
149
151 std::unordered_set<std::string> currently_creating_sink_names_{};
152};
153
154} // namespace num_collect::logging::config
Class of exception on invalid arguments.
Definition exception.h:85
auto get(log_sink_factory_table &sinks) -> sinks::log_sink
Get the log sink creating it if needed.
cached_log_sink(std::shared_ptr< log_sink_factory_base > factory)
Constructor.
std::shared_ptr< log_sink_factory_base > factory_
Factory of the log sink.
void check_sink_reference_loop(std::string name)
Check whether a log sink can be created without loop of references.
void append(const std::string &name, const std::shared_ptr< log_sink_factory_base > &sink_factory)
Append a factory of a log sink.
std::unordered_set< std::string > currently_creating_sink_names_
Names of currently creating sinks.
void pop_created_log_sink_name(const std::string &name)
Pop a name of a created log sink from currently_creating_sink_names_.
auto get(const std::string &name) -> sinks::log_sink
Get a log sink creating it if needed.
std::unordered_map< std::string, cached_log_sink > caches_
Caches.
Definition of default_log_sink_factory class.
Definition of exceptions.
Definition of log_sink class.
Definition of log_sink_factory_base class.
Namespace of logging configuration.
constexpr auto default_log_sink_name
Name of the default log sink.
STL namespace.