Added log levels
This commit is contained in:
parent
d52da6976a
commit
a5a42e8e77
2
PKGBUILD
2
PKGBUILD
@ -1,7 +1,7 @@
|
|||||||
# Maintainer: Matthias Quintern <matthiasqui@protonmail.com>
|
# Maintainer: Matthias Quintern <matthiasqui@protonmail.com>
|
||||||
pkgname=gz-cpp-util
|
pkgname=gz-cpp-util
|
||||||
pkgver=1.3
|
pkgver=1.3
|
||||||
pkgrel=1
|
pkgrel=2
|
||||||
pkgdesc="Utility library for c++"
|
pkgdesc="Utility library for c++"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
url="https://github.com/MatthiasQuintern/gz-cpp-util"
|
url="https://github.com/MatthiasQuintern/gz-cpp-util"
|
||||||
|
16
README.md
16
README.md
@ -48,10 +48,12 @@ Replace `firefox` with your web browser
|
|||||||
|
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
### 2022-10-14
|
### 2022-10-19 [1.3.1] [1.3.2]
|
||||||
- Added create info struct constructor to log
|
- Changes to logger (log.hpp):
|
||||||
- Timestamp can be disabled in log
|
- Added create info struct constructor
|
||||||
### 2022-09-26
|
- Timestamp can be disabled
|
||||||
|
- Added different log levels that can be turned off/on at compile time
|
||||||
|
### 2022-09-26 [1.3]
|
||||||
- Added SettingsManager
|
- Added SettingsManager
|
||||||
- Renamed getXXX to getXXXOr
|
- Renamed getXXX to getXXXOr
|
||||||
- Added more type conversion utility
|
- Added more type conversion utility
|
||||||
@ -60,10 +62,10 @@ Replace `firefox` with your web browser
|
|||||||
- Logger now uses to_string
|
- Logger now uses to_string
|
||||||
- Restructured files
|
- Restructured files
|
||||||
- Added more documentation
|
- Added more documentation
|
||||||
### 2022-09-17
|
### 2022-09-17 [1.2]
|
||||||
- Moved math part to its own repository/library [here](https://github.com/MatthiasQuintern/gzm)
|
- Moved math part to its own repository/library [here](https://github.com/MatthiasQuintern/gzm)
|
||||||
### 2022-09-10
|
### 2022-09-10 [1.1]
|
||||||
- Added matrices to math lib
|
- Added matrices to math lib
|
||||||
- Improved logger
|
- Improved logger
|
||||||
### 2022-09-05
|
### 2022-09-05 [1.0]
|
||||||
- initial version
|
- initial version
|
||||||
|
340
src/log.hpp
340
src/log.hpp
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#define LOG_MULTITHREAD
|
|
||||||
|
|
||||||
#include "util/string_conversion.hpp"
|
#include "util/string_conversion.hpp"
|
||||||
|
|
||||||
@ -12,6 +11,19 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// the higher level needs to include the lower ones
|
||||||
|
#ifdef LOG_LEVEL_3
|
||||||
|
#define LOG_LEVEL_2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOG_LEVEL_2
|
||||||
|
#define LOG_LEVEL_1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LOG_LEVEL_1
|
||||||
|
#define LOG_LEVEL_0
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace gz {
|
namespace gz {
|
||||||
/// Reserve a string size for each string in logArray. Set to 0 if you do not want to reserve memory for strings.
|
/// Reserve a string size for each string in logArray. Set to 0 if you do not want to reserve memory for strings.
|
||||||
constexpr unsigned int LOG_RESERVE_STRING_SIZE = 100;
|
constexpr unsigned int LOG_RESERVE_STRING_SIZE = 100;
|
||||||
@ -101,18 +113,29 @@ namespace gz {
|
|||||||
* Alternatively, or if the type is not a class overload <code> std::string toString(const T& t) </code> in global or gz namespace.
|
* Alternatively, or if the type is not a class overload <code> std::string toString(const T& t) </code> in global or gz namespace.
|
||||||
*
|
*
|
||||||
* @subsection log_threads Thread safety
|
* @subsection log_threads Thread safety
|
||||||
* Log can use a static mutex for thread safety. To use this feature, you have to #define LOG_MULTITHREAD at the top of log.hpp.
|
* Log can use a static mutex for thread safety. To use this feature, you have to `#define LOG_MULTITHREAD` @b before including `log.hpp`.
|
||||||
* Note that log uses the default std::cout buffer, so you should make sure it is not being used while logging something.
|
* Note that log uses the default std::cout buffer, so you should make sure it is not being used while logging something.
|
||||||
*
|
*
|
||||||
* @subsection log_logfile Logfile
|
* @subsection log_logfile Logfile
|
||||||
* The logs can be written to a logfile, which can be specified in the constructor.
|
* The logs can be written to a logfile, which can be specified in the constructor.
|
||||||
* The logs are not continuously written to the logfile, since file operations are expensive.
|
* The logs are not continuously written to the logfile, since file operations are expensive.
|
||||||
* Instead, the log is stored in memory and written to the file if a certain number of lines is reached, which you can specify in the constructor.
|
* Instead, the log is stored in memory and written to the file if a certain number of lines is reached, which you can specify in the constructor.
|
||||||
* If you want the the log to be continuously written to the file, set writeAfterLines=1.
|
* If you want the log to be continuously written to the file, set `writeAfterLines` to 1.
|
||||||
*
|
*
|
||||||
|
* @subsection log_levels Loglevels
|
||||||
|
* There are 4 different log levels (0-3), where the higher ones include the lower ones.
|
||||||
|
* To set the log level to `X`, where `X` is one of {0, 1, 2, 3},
|
||||||
|
* define `#define LOG_LEVEL_X` @b before including `log.hpp`.
|
||||||
|
* You can then use @ref log0 "logX" or @ref clog0 "clogX".
|
||||||
|
*
|
||||||
|
* If @ref log0 "logX" function log level is higher than the set log level,
|
||||||
|
* the function call will be a noop and thus optimized away be the compiler.
|
||||||
|
*
|
||||||
|
* @note operator(), log, clog, warning and error are always 'on', regardless of which (if any) log level is defined.
|
||||||
|
*
|
||||||
* @todo Exception policies
|
* @todo Exception policies
|
||||||
* @todo Remove vec2 or add vec3, vec4
|
* @todo Use own ostream and not std::cout
|
||||||
*
|
* @todo Make colors cross platform
|
||||||
*/
|
*/
|
||||||
class Log {
|
class Log {
|
||||||
public:
|
public:
|
||||||
@ -139,6 +162,10 @@ class Log {
|
|||||||
//
|
//
|
||||||
// ACTUAL LOGGING
|
// ACTUAL LOGGING
|
||||||
//
|
//
|
||||||
|
/**
|
||||||
|
* @name Logging
|
||||||
|
*/
|
||||||
|
/// @{
|
||||||
/**
|
/**
|
||||||
* @brief Logs a message
|
* @brief Logs a message
|
||||||
* @details Depending on the settings of the log instance, the message will be printed to stdout and/or written to the logfile.
|
* @details Depending on the settings of the log instance, the message will be printed to stdout and/or written to the logfile.
|
||||||
@ -149,41 +176,7 @@ class Log {
|
|||||||
* @param args Any number of arguments that satisfy concept Logable
|
* @param args Any number of arguments that satisfy concept Logable
|
||||||
*/
|
*/
|
||||||
template<Logable... Args>
|
template<Logable... Args>
|
||||||
void log(Args&&... args) {
|
void log(Args&&... args);
|
||||||
#ifdef LOG_MULTITHREAD
|
|
||||||
mtx.lock();
|
|
||||||
#endif
|
|
||||||
argsBegin.clear();
|
|
||||||
if (showTime) {
|
|
||||||
getTime();
|
|
||||||
logLines[iter] = time;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logLines.clear();
|
|
||||||
}
|
|
||||||
argsBegin.emplace_back(logLines[iter].size());
|
|
||||||
logLines[iter] += prefix;
|
|
||||||
|
|
||||||
vlog(" ", std::forward<Args>(args)...);
|
|
||||||
logLines[iter] += "\n";
|
|
||||||
argsBegin.emplace_back(logLines[iter].size());
|
|
||||||
|
|
||||||
if (showLog) {
|
|
||||||
// time
|
|
||||||
std::cout << COLORS[timeColor] << std::string_view(logLines[iter].begin(), logLines[iter].begin() + argsBegin[0])
|
|
||||||
// prefix
|
|
||||||
<< COLORS[prefixColor] << std::string_view(logLines[iter].begin() + argsBegin[0], logLines[iter].begin() + argsBegin[1]) << COLORS[RESET]
|
|
||||||
// message
|
|
||||||
<< std::string_view(logLines[iter].begin() + argsBegin[1], logLines[iter].end());
|
|
||||||
}
|
|
||||||
if (++iter >= writeToFileAfterLines) {
|
|
||||||
iter = 0;
|
|
||||||
writeLog();
|
|
||||||
}
|
|
||||||
#ifdef LOG_MULTITHREAD
|
|
||||||
mtx.unlock();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Log a message in a certain color
|
* @brief Log a message in a certain color
|
||||||
@ -196,46 +189,7 @@ class Log {
|
|||||||
* @param colors Vector of colors, where the nth color refers to the nth arg
|
* @param colors Vector of colors, where the nth color refers to the nth arg
|
||||||
*/
|
*/
|
||||||
template<Logable... Args>
|
template<Logable... Args>
|
||||||
void clog(const std::vector<Color>& colors, Args&&... args) {
|
void clog(const std::vector<Color>& colors, Args&&... args);
|
||||||
#ifdef LOG_MULTITHREAD
|
|
||||||
mtx.lock();
|
|
||||||
#endif
|
|
||||||
argsBegin.clear();
|
|
||||||
if (showTime) {
|
|
||||||
getTime();
|
|
||||||
logLines[iter] = std::string(time);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logLines.clear();
|
|
||||||
}
|
|
||||||
argsBegin.emplace_back(logLines[iter].size());
|
|
||||||
logLines[iter] += prefix;
|
|
||||||
|
|
||||||
vlog(" ", std::forward<Args>(args)...);
|
|
||||||
logLines[iter] += "\n";
|
|
||||||
argsBegin.emplace_back(logLines[iter].size());
|
|
||||||
|
|
||||||
if (showLog) {
|
|
||||||
// time
|
|
||||||
std::cout << COLORS[timeColor] << std::string_view(logLines[iter].begin(), logLines[iter].begin() + argsBegin[0])
|
|
||||||
// prefix
|
|
||||||
<< COLORS[prefixColor] << std::string_view(logLines[iter].begin() + argsBegin[0], logLines[iter].begin() + argsBegin[1]) << COLORS[RESET];
|
|
||||||
// max index where i can be used for colors and i+2 can be used for currentViews
|
|
||||||
size_t maxI = std::min(colors.size(), argsBegin.size() - 2);
|
|
||||||
for (size_t i = 0; i < maxI; i++) {
|
|
||||||
std::cout << COLORS[colors[i]] << std::string_view(logLines[iter].begin() + argsBegin[i+1], logLines[iter].begin() + argsBegin[i+2]);
|
|
||||||
}
|
|
||||||
// log the rest, maxI is now <= argsBegin.size() - 2
|
|
||||||
std::cout << std::string_view(logLines[iter].begin() + argsBegin[maxI+1], logLines[iter].end()) << COLORS[RESET];
|
|
||||||
}
|
|
||||||
if (++iter >= writeToFileAfterLines) {
|
|
||||||
iter = 0;
|
|
||||||
writeLog();
|
|
||||||
}
|
|
||||||
#ifdef LOG_MULTITHREAD
|
|
||||||
mtx.unlock();
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -263,7 +217,7 @@ class Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Log a warnign
|
* @brief Log a warning
|
||||||
* @details Prints the message with a yellow "Warning: " prefix.
|
* @details Prints the message with a yellow "Warning: " prefix.
|
||||||
* The message will look like this:
|
* The message will look like this:
|
||||||
* <time>: <prefix>: Warning: <message>
|
* <time>: <prefix>: Warning: <message>
|
||||||
@ -274,26 +228,65 @@ class Log {
|
|||||||
void warning(Args&&... args) {
|
void warning(Args&&... args) {
|
||||||
clog({YELLOW, WHITE}, "Warning:", std::forward<Args>(args)...);
|
clog({YELLOW, WHITE}, "Warning:", std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
/// @}
|
||||||
|
/**
|
||||||
|
* @name Logging at different levels
|
||||||
|
*/
|
||||||
|
/// @{
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_0 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void log0(Args&&... args);
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_1 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void log1(Args&&... args);
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_2 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void log2(Args&&... args);
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_3 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void log3(Args&&... args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_0 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void clog0(const std::vector<Color>& colors, Args&&... args);
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_1 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void clog1(const std::vector<Color>& colors, Args&&... args);
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_2 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void clog2(const std::vector<Color>& colors, Args&&... args);
|
||||||
|
/**
|
||||||
|
* @brief Enabled with LOG_LEVEL_3 or higher
|
||||||
|
*/
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void clog3(const std::vector<Color>& colors, Args&&... args);
|
||||||
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// vlog for variadic log
|
// vlog for variadic log
|
||||||
/// Log anything that can be appendend to std::string
|
/// Log anything that can be appendend to std::string
|
||||||
template<util::Stringy T, Logable... Args>
|
template<util::Stringy T, Logable... Args>
|
||||||
void vlog(const char* appendChars, T&& t, Args&&... args) {
|
void vlog(const char* appendChars, T&& t, Args&&... args);
|
||||||
argsBegin.emplace_back(logLines[iter].size());
|
|
||||||
logLines[iter] += std::string(t);
|
|
||||||
logLines[iter] += appendChars;
|
|
||||||
vlog(" ", std::forward< Args>(args)...);
|
|
||||||
}
|
|
||||||
/// Log anything where toString exists
|
/// Log anything where toString exists
|
||||||
template<ConvertibleToString T, Logable... Args>
|
template<ConvertibleToString T, Logable... Args>
|
||||||
void vlog(const char* appendChars, T&& t, Args&&... args) requires (!util::Stringy<T>) {
|
void vlog(const char* appendChars, T&& t, Args&&... args) requires (!util::Stringy<T>);
|
||||||
argsBegin.emplace_back(logLines[iter].size());
|
|
||||||
logLines[iter] += toString(t);
|
|
||||||
logLines[iter] += appendChars;
|
|
||||||
vlog(" ", std::forward< Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/// End for the recursion
|
||||||
void vlog(const char* appendChars) {};
|
void vlog(const char* appendChars) {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -338,6 +331,167 @@ class Log {
|
|||||||
static std::mutex mtx;
|
static std::mutex mtx;
|
||||||
#endif
|
#endif
|
||||||
}; // class Log
|
}; // class Log
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DEFINITIONS
|
||||||
|
//
|
||||||
|
template<Logable... Args>
|
||||||
|
void Log::log(Args&&... args) {
|
||||||
|
#ifdef LOG_MULTITHREAD
|
||||||
|
mtx.lock();
|
||||||
|
#endif
|
||||||
|
argsBegin.clear();
|
||||||
|
if (showTime) {
|
||||||
|
getTime();
|
||||||
|
logLines[iter] = time;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logLines.clear();
|
||||||
|
}
|
||||||
|
argsBegin.emplace_back(logLines[iter].size());
|
||||||
|
logLines[iter] += prefix;
|
||||||
|
|
||||||
|
vlog(" ", std::forward<Args>(args)...);
|
||||||
|
logLines[iter] += "\n";
|
||||||
|
argsBegin.emplace_back(logLines[iter].size());
|
||||||
|
|
||||||
|
if (showLog) {
|
||||||
|
// time
|
||||||
|
std::cout << COLORS[timeColor] << std::string_view(logLines[iter].begin(), logLines[iter].begin() + argsBegin[0])
|
||||||
|
// prefix
|
||||||
|
<< COLORS[prefixColor] << std::string_view(logLines[iter].begin() + argsBegin[0], logLines[iter].begin() + argsBegin[1]) << COLORS[RESET]
|
||||||
|
// message
|
||||||
|
<< std::string_view(logLines[iter].begin() + argsBegin[1], logLines[iter].end());
|
||||||
|
}
|
||||||
|
if (++iter >= writeToFileAfterLines) {
|
||||||
|
iter = 0;
|
||||||
|
writeLog();
|
||||||
|
}
|
||||||
|
#ifdef LOG_MULTITHREAD
|
||||||
|
mtx.unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
void Log::clog(const std::vector<Color>& colors, Args&&... args) {
|
||||||
|
#ifdef LOG_MULTITHREAD
|
||||||
|
mtx.lock();
|
||||||
|
#endif
|
||||||
|
argsBegin.clear();
|
||||||
|
if (showTime) {
|
||||||
|
getTime();
|
||||||
|
logLines[iter] = std::string(time);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logLines.clear();
|
||||||
|
}
|
||||||
|
argsBegin.emplace_back(logLines[iter].size());
|
||||||
|
logLines[iter] += prefix;
|
||||||
|
|
||||||
|
vlog(" ", std::forward<Args>(args)...);
|
||||||
|
logLines[iter] += "\n";
|
||||||
|
argsBegin.emplace_back(logLines[iter].size());
|
||||||
|
|
||||||
|
if (showLog) {
|
||||||
|
// time
|
||||||
|
std::cout << COLORS[timeColor] << std::string_view(logLines[iter].begin(), logLines[iter].begin() + argsBegin[0])
|
||||||
|
// prefix
|
||||||
|
<< COLORS[prefixColor] << std::string_view(logLines[iter].begin() + argsBegin[0], logLines[iter].begin() + argsBegin[1]) << COLORS[RESET];
|
||||||
|
// max index where i can be used for colors and i+2 can be used for currentViews
|
||||||
|
size_t maxI = std::min(colors.size(), argsBegin.size() - 2);
|
||||||
|
for (size_t i = 0; i < maxI; i++) {
|
||||||
|
std::cout << COLORS[colors[i]] << std::string_view(logLines[iter].begin() + argsBegin[i+1], logLines[iter].begin() + argsBegin[i+2]);
|
||||||
|
}
|
||||||
|
// log the rest, maxI is now <= argsBegin.size() - 2
|
||||||
|
std::cout << std::string_view(logLines[iter].begin() + argsBegin[maxI+1], logLines[iter].end()) << COLORS[RESET];
|
||||||
|
}
|
||||||
|
if (++iter >= writeToFileAfterLines) {
|
||||||
|
iter = 0;
|
||||||
|
writeLog();
|
||||||
|
}
|
||||||
|
#ifdef LOG_MULTITHREAD
|
||||||
|
mtx.unlock();
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<util::Stringy T, Logable... Args>
|
||||||
|
void Log::vlog(const char* appendChars, T&& t, Args&&... args) {
|
||||||
|
argsBegin.emplace_back(logLines[iter].size());
|
||||||
|
logLines[iter] += std::string(t);
|
||||||
|
logLines[iter] += appendChars;
|
||||||
|
vlog(" ", std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
/// Log anything where toString exists
|
||||||
|
template<ConvertibleToString T, Logable... Args>
|
||||||
|
void Log::vlog(const char* appendChars, T&& t, Args&&... args) requires (!util::Stringy<T>) {
|
||||||
|
argsBegin.emplace_back(logLines[iter].size());
|
||||||
|
logLines[iter] += toString(t);
|
||||||
|
logLines[iter] += appendChars;
|
||||||
|
vlog(" ", std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::log0(Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_0
|
||||||
|
this->log(std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::log1(Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_1
|
||||||
|
this->log(std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::log2(Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_2
|
||||||
|
this->log(std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::log3(Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_3
|
||||||
|
this->log(std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::clog0(const std::vector<Color>& colors, Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_0
|
||||||
|
this->clog(colors, std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::clog1(const std::vector<Color>& colors, Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_1
|
||||||
|
this->clog(colors, std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::clog2(const std::vector<Color>& colors, Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_2
|
||||||
|
this->clog(colors, std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Logable... Args>
|
||||||
|
inline void Log::clog3(const std::vector<Color>& colors, Args&&... args) {
|
||||||
|
#ifdef LOG_LEVEL_3
|
||||||
|
this->clog(colors, std::forward<Args>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace gz
|
} // namespace gz
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user