15 * conv::to_string will be used to convert whatever argument is send
16 * to the logger to a string. If another type shall be supported,
17 * just add the appropriate overload and you can start using it right
18 * away. The default conversion will use a stringstream.
22 inline std::string to_string( const T& arg ) {
23 std::ostringstream stream;
27 inline std::string to_string( std::string&& arg ) {
30 inline std::string to_string( const std::string& arg ) {
33 inline std::string to_string( const char* arg ) {
40 debug, note, warn, error, fatal
43 const auto default_level = level::note;
46 log_target( std::ostream& stream, level min_level = default_level ):
47 stream {&stream}, min_level {min_level} {}
48 log_target( std::ofstream& stream, level min_level = default_level ):
49 stream {&stream}, min_level {min_level} {
50 if( !stream.is_open() ) {
51 throw std::runtime_error {"logfile not open"};
60 void reassign_stack_pointer( logger_set*& ptr );
64 * Provides controll over wether a logger should automatically register itself
66 enum class auto_register {
72 logger_set( std::initializer_list<log_target> lst, auto_register = auto_register::on );
74 logger_set( logger_set&& ) noexcept;
75 logger_set& operator=( logger_set && ) noexcept;
78 template<typename... Args>
79 void log( level l, Args&& ... args );
80 template<typename... Args>
81 void logf( level l, const std::string& format, Args&& ... args );
83 template<typename... Args>
84 void debug( Args&& ... args );
85 template<typename... Args>
86 void debugf( const std::string& format, Args&& ... args );
88 template<typename... Args>
89 void note( Args&& ... args );
90 template<typename... Args>
91 void notef( const std::string& format, Args&& ... args );
93 template<typename... Args>
94 void warn( Args&& ... args );
95 template<typename... Args>
96 void warnf( const std::string& format, Args&& ... args );
98 template<typename... Args>
99 void error( Args&& ... args );
100 template<typename... Args>
101 void errorf( const std::string& format, Args&& ... args );
103 template<typename... Args>
104 void fatal( Args&& ... args );
105 template<typename... Args>
106 void fatalf( const std::string& format, Args&& ... args );
108 friend void impl::reassign_stack_pointer( logger_set*& ptr );
109 friend logger_set current_logger_extended( std::initializer_list<log_target> further_targets );
111 void log_impl( level l, const std::string& msg );
113 std::vector<log_target> m_loggers;
114 logger_set** m_stackpointer = nullptr;
118 logger_set current_logger_extended( std::initializer_list<log_target> further_targets );
121 std::string concat_msg( level l, const std::vector<std::string>& args );
122 std::string format_msg( level l, const std::string&, std::vector<std::string> args );
123 logger_set& active_logger();
126 template <typename... Args>
127 void logger_set::log( level l, Args&& ... data ) {
128 if( l < m_min_level ) {
132 log_impl( l, impl::concat_msg( l, {conv::to_string( std::forward<Args>( data ) )...} ) );
135 template <typename... Args>
136 void logger_set::logf( level l, const std::string& format, Args&& ... data ) {
137 if( l < m_min_level ) {
141 log_impl( l, impl::format_msg( l, format, {conv::to_string( std::forward<Args>( data ) )...} ) );
144 template <typename... Args>
145 void log( level l, Args&& ... args ) {
146 impl::active_logger().log( l, std::forward<Args>( args )... );
148 template <typename... Args>
149 void logf( level l, const std::string& format, Args&& ... args ) {
150 impl::active_logger().logf( l, format, std::forward<Args>( args )... );
153 // concat-based methods
154 template <typename... Args>
155 void logger_set::debug( Args&& ... args ) {
156 log( level::debug, std::forward<Args>( args )... );
158 template <typename... Args>
159 void logger_set::note( Args&& ... args ) {
160 log( level::note, std::forward<Args>( args )... );
162 template <typename... Args>
163 void logger_set::warn( Args&& ... args ) {
164 log( level::warn, std::forward<Args>( args )... );
166 template <typename... Args>
167 void logger_set::error( Args&& ... args ) {
168 log( level::error, std::forward<Args>( args )... );
170 template <typename... Args>
171 void logger_set::fatal( Args&& ... args ) {
172 log( level::fatal, std::forward<Args>( args )... );
175 // format-based methods
176 template <typename... Args>
177 void logger_set::debugf( const std::string& fmt, Args&& ... args ) {
178 logf( level::debug, fmt, std::forward<Args>( args )... );
180 template <typename... Args>
181 void logger_set::notef( const std::string& fmt, Args&& ... args ) {
182 logf( level::note, fmt, std::forward<Args>( args )... );
184 template <typename... Args>
185 void logger_set::warnf( const std::string& fmt, Args&& ... args ) {
186 logf( level::warn, fmt, std::forward<Args>( args )... );
188 template <typename... Args>
189 void logger_set::errorf( const std::string& fmt, Args&& ... args ) {
190 logf( level::error, fmt, std::forward<Args>( args )... );
192 template <typename... Args>
193 void logger_set::fatalf( const std::string& fmt, Args&& ... args ) {
194 logf( level::fatal, fmt, std::forward<Args>( args )... );
197 // global concat-based
198 template <typename... Args>
199 void debug( Args&& ... args ) {
200 log( level::debug, std::forward<Args>( args )... );
202 template <typename... Args>
203 void note( Args&& ... args ) {
204 log( level::note, std::forward<Args>( args )... );
206 template <typename... Args>
207 void warn( Args&& ... args ) {
208 log( level::warn, std::forward<Args>( args )... );
210 template <typename... Args>
211 void error( Args&& ... args ) {
212 log( level::error, std::forward<Args>( args )... );
214 template <typename... Args>
215 void fatal( Args&& ... args ) {
216 log( level::fatal, std::forward<Args>( args )... );
219 // global format-based
220 template <typename... Args>
221 void debugf( const std::string& fmt, Args&& ... args ) {
222 logf( level::debug, fmt, std::forward<Args>( args )... );
224 template <typename... Args>
225 void notef( const std::string& fmt, Args&& ... args ) {
226 logf( level::note, fmt, std::forward<Args>( args )... );
228 template <typename... Args>
229 void warnf( const std::string& fmt, Args&& ... args ) {
230 logf( level::warn, fmt, std::forward<Args>( args )... );
232 template <typename... Args>
233 void errorf( const std::string& fmt, Args&& ... args ) {
234 logf( level::error, fmt, std::forward<Args>( args )... );
236 template <typename... Args>
237 void fatalf( const std::string& fmt, Args&& ... args ) {
238 logf( level::fatal, fmt, std::forward<Args>( args )... );