14 * conv::to_string will be used to convert whatever argument is send
15 * to the logger to a string. If another type shall be supported,
16 * just add the appropriate overload and you can start using it right
17 * away. The default conversion will use a stringstream.
21 inline std::string to_string( const T& arg ) {
22 std::ostringstream stream;
26 inline std::string to_string( std::string&& arg ) {
29 inline std::string to_string( const std::string& arg ) {
32 inline std::string to_string( const char* arg ) {
39 debug, note, warn, error, fatal
42 const auto default_level = level::note;
45 log_target( std::ostream& stream, level min_level = default_level ):
46 stream {&stream}, min_level {min_level} {}
47 log_target( std::ofstream& stream, level min_level = default_level ):
48 stream {&stream}, min_level {min_level} {
49 if( !stream.is_open() ) {
50 throw std::runtime_error {"logfile not open"};
59 void reassign_stack_pointer( logger_set*& ptr );
63 * Provides controll over wether a logger should automatically register itself
65 enum class auto_register {
71 logger_set( std::initializer_list<log_target> lst, auto_register = auto_register::on );
73 logger_set( logger_set&& ) noexcept;
74 logger_set& operator=( logger_set && ) noexcept;
77 template<typename... Args>
78 void log( level l, Args&& ... args );
79 template<typename... Args>
80 void logf( level l, const std::string& format, Args&& ... args );
82 template<typename... Args>
83 void debug( Args&& ... args );
84 template<typename... Args>
85 void debugf( const std::string& format, Args&& ... args );
87 template<typename... Args>
88 void note( Args&& ... args );
89 template<typename... Args>
90 void notef( const std::string& format, Args&& ... args );
92 template<typename... Args>
93 void warn( Args&& ... args );
94 template<typename... Args>
95 void warnf( const std::string& format, Args&& ... args );
97 template<typename... Args>
98 void error( Args&& ... args );
99 template<typename... Args>
100 void errorf( const std::string& format, Args&& ... args );
102 template<typename... Args>
103 void fatal( Args&& ... args );
104 template<typename... Args>
105 void fatalf( const std::string& format, Args&& ... args );
107 friend void impl::reassign_stack_pointer( logger_set*& ptr );
108 friend logger_set current_logger_extended( std::initializer_list<log_target> further_targets );
110 void log_impl( level l, const std::string& msg );
112 std::vector<log_target> m_loggers;
113 logger_set** m_stackpointer = nullptr;
117 logger_set current_logger_extended( std::initializer_list<log_target> further_targets );
120 std::string concat_msg( level l, const std::vector<std::string>& args );
121 std::string format_msg( level l, const std::string&, std::vector<std::string> args );
122 logger_set& active_logger();
125 template <typename... Args>
126 void logger_set::log( level l, Args&& ... data ) {
127 if( l < m_min_level ) {
131 log_impl( l, impl::concat_msg( l, {conv::to_string( std::forward<Args>( data ) )...} ) );
134 template <typename... Args>
135 void logger_set::logf( level l, const std::string& format, Args&& ... data ) {
136 if( l < m_min_level ) {
140 log_impl( l, impl::format_msg( l, format, {conv::to_string( std::forward<Args>( data ) )...} ) );
143 template <typename... Args>
144 void log( level l, Args&& ... args ) {
145 impl::active_logger().log( l, std::forward<Args>( args )... );
147 template <typename... Args>
148 void logf( level l, const std::string& format, Args&& ... args ) {
149 impl::active_logger().logf( l, format, std::forward<Args>( args )... );
152 // concat-based methods
153 template <typename... Args>
154 void logger_set::debug( Args&& ... args ) {
155 log( level::debug, std::forward<Args>( args )... );
157 template <typename... Args>
158 void logger_set::note( Args&& ... args ) {
159 log( level::note, std::forward<Args>( args )... );
161 template <typename... Args>
162 void logger_set::warn( Args&& ... args ) {
163 log( level::warn, std::forward<Args>( args )... );
165 template <typename... Args>
166 void logger_set::error( Args&& ... args ) {
167 log( level::error, std::forward<Args>( args )... );
169 template <typename... Args>
170 void logger_set::fatal( Args&& ... args ) {
171 log( level::fatal, std::forward<Args>( args )... );
174 // format-based methods
175 template <typename... Args>
176 void logger_set::debugf( const std::string& fmt, Args&& ... args ) {
177 logf( level::debug, fmt, std::forward<Args>( args )... );
179 template <typename... Args>
180 void logger_set::notef( const std::string& fmt, Args&& ... args ) {
181 logf( level::note, fmt, std::forward<Args>( args )... );
183 template <typename... Args>
184 void logger_set::warnf( const std::string& fmt, Args&& ... args ) {
185 logf( level::warn, fmt, std::forward<Args>( args )... );
187 template <typename... Args>
188 void logger_set::errorf( const std::string& fmt, Args&& ... args ) {
189 logf( level::error, fmt, std::forward<Args>( args )... );
191 template <typename... Args>
192 void logger_set::fatalf( const std::string& fmt, Args&& ... args ) {
193 logf( level::fatal, fmt, std::forward<Args>( args )... );
196 // global concat-based
197 template <typename... Args>
198 void debug( Args&& ... args ) {
199 log( level::debug, std::forward<Args>( args )... );
201 template <typename... Args>
202 void note( Args&& ... args ) {
203 log( level::note, std::forward<Args>( args )... );
205 template <typename... Args>
206 void warn( Args&& ... args ) {
207 log( level::warn, std::forward<Args>( args )... );
209 template <typename... Args>
210 void error( Args&& ... args ) {
211 log( level::error, std::forward<Args>( args )... );
213 template <typename... Args>
214 void fatal( Args&& ... args ) {
215 log( level::fatal, std::forward<Args>( args )... );
218 // global format-based
219 template <typename... Args>
220 void debugf( const std::string& fmt, Args&& ... args ) {
221 logf( level::debug, fmt, std::forward<Args>( args )... );
223 template <typename... Args>
224 void notef( const std::string& fmt, Args&& ... args ) {
225 logf( level::note, fmt, std::forward<Args>( args )... );
227 template <typename... Args>
228 void warnf( const std::string& fmt, Args&& ... args ) {
229 logf( level::warn, fmt, std::forward<Args>( args )... );
231 template <typename... Args>
232 void errorf( const std::string& fmt, Args&& ... args ) {
233 logf( level::error, fmt, std::forward<Args>( args )... );
235 template <typename... Args>
236 void fatalf( const std::string& fmt, Args&& ... args ) {
237 logf( level::fatal, fmt, std::forward<Args>( args )... );