Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 24 additions & 21 deletions include/zeroerr/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
#include "zeroerr/print.h"

#include <chrono>
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
#include <iosfwd>

ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH

Expand Down Expand Up @@ -80,7 +80,7 @@ namespace zeroerr {

#define ZEROERR_LOG_EVERY_(n, ACTION, ...) \
do { \
unsigned counter = 0; \
static unsigned counter = 0; \
if (counter == 0) { \
counter = n; \
ACTION(__VA_ARGS__); \
Expand All @@ -98,12 +98,14 @@ namespace zeroerr {

#define ZEROERR_LOG_IF_EVERY_(n, cond, ACTION, ...) \
do { \
unsigned counter = 0; \
if (counter == 0 && (cond)) { \
counter = n; \
ACTION(__VA_ARGS__); \
if (cond) { \
static unsigned counter = 0; \
if (counter == 0) { \
counter = n; \
ACTION(__VA_ARGS__); \
} \
--counter; \
} \
--counter; \
} while (0)

#define INFO_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_INFO, __VA_ARGS__)
Expand All @@ -114,7 +116,7 @@ namespace zeroerr {

#define ZEROERR_LOG_FIRST(cond, ACTION, ...) \
do { \
bool first = true; \
static bool first = true; \
if (first && (cond)) { \
first = false; \
ACTION(__VA_ARGS__); \
Expand All @@ -129,8 +131,9 @@ namespace zeroerr {

#define ZEROERR_LOG_FIRST_(n, cond, ACTION, ...) \
do { \
unsigned counter = n; \
if (n-- && (cond)) { \
static unsigned counter = n; \
if (counter && (cond)) { \
counter--; \
ACTION(__VA_ARGS__); \
} \
} while (0)
Expand Down Expand Up @@ -227,24 +230,24 @@ enum LogSeverity {

/**
* @brief LogInfo is a struct to store the meta data of the log message.
* @details LogInfo is a struct to store the meta data of the log message.
* @details LogInfo is a struct to store the meta data of the log message.
* It contains filename, function, message, category, line number, size, and severity.
* Those data is initialized when the first log message is created using a static
* local variable in the function where the log message is put.
*
*
* For example:
* void foo() {
* log("Hello, {name}!", "John");
* }
*
* The inner implementation could be considered as (not exactly
*
* The inner implementation could be considered as (not exactly
* since message is allocated from a pool):
* void foo() {
* static LogInfo log_info{
* __FILE__, __func__, "Hello, {name}!",
* ZEROERR_LOG_CATEGORY,
* __LINE__,
* sizeof("Hello, world!"),
* static LogInfo log_info{
* __FILE__, __func__, "Hello, {name}!",
* ZEROERR_LOG_CATEGORY,
* __LINE__,
* sizeof("Hello, world!"),
* LogSeverity::INFO_l);
* LogMessage* logdata = new LogMessageImpl<std::string>("John");
* logdata->info = &log_info;
Expand Down Expand Up @@ -498,11 +501,11 @@ class LogStream {
* The log message is structured as a tuple of the arguments in the inner
* implementation class LogMessageImpl. After the log message is created, it
* used type erasure to return a LogMessage pointer to the caller.
*
*
* The stored data type is determined by the to_store_type_t<T> template.
* For all the string type in raw pointer like const char* or char[],
* it will be converted to std::string.
* All reference type (including right value reference) will be converted
* All reference type (including right value reference) will be converted
* to the original type.
*/
template <typename... T>
Expand Down
14 changes: 13 additions & 1 deletion test/log_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ TEST_CASE("log_test") {
ERR_IF(1 == 1, "1 == 1");

for (int i = 0; i < 10; ++i) {
LOG_EVERY_(3, "log every 3 times {i}", i);
LOG_EVERY_(3, "log every 3 times: {i}", i);
}

for (int i = 0; i < 10; ++i) {
LOG_FIRST(i % 2 == 0, "log first even number: {i}", i);
}

for (int i = 0; i < 10; ++i) {
LOG_FIRST(i % 2 == 1, "log first odd number: {i}", i);
}

for (int i = 0; i < 10; ++i) {
LOG_IF_EVERY_(3, i % 2 == 1, "log every 3 times odd number: {i}", i);
}
}

Expand Down
45 changes: 24 additions & 21 deletions zeroerr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3387,10 +3387,10 @@ std::string format(const char* fmt, T... args) {


#include <chrono>
#include <iosfwd>
#include <map>
#include <string>
#include <vector>
#include <iosfwd>

ZEROERR_SUPPRESS_COMMON_WARNINGS_PUSH

Expand Down Expand Up @@ -3458,7 +3458,7 @@ namespace zeroerr {

#define ZEROERR_LOG_EVERY_(n, ACTION, ...) \
do { \
unsigned counter = 0; \
static unsigned counter = 0; \
if (counter == 0) { \
counter = n; \
ACTION(__VA_ARGS__); \
Expand All @@ -3476,12 +3476,14 @@ namespace zeroerr {

#define ZEROERR_LOG_IF_EVERY_(n, cond, ACTION, ...) \
do { \
unsigned counter = 0; \
if (counter == 0 && (cond)) { \
counter = n; \
ACTION(__VA_ARGS__); \
if (cond) { \
static unsigned counter = 0; \
if (counter == 0) { \
counter = n; \
ACTION(__VA_ARGS__); \
} \
--counter; \
} \
--counter; \
} while (0)

#define INFO_IF_EVERY_(n, cond, ...) ZEROERR_LOG_IF_EVERY_(n, cond, ZEROERR_INFO, __VA_ARGS__)
Expand All @@ -3492,7 +3494,7 @@ namespace zeroerr {

#define ZEROERR_LOG_FIRST(cond, ACTION, ...) \
do { \
bool first = true; \
static bool first = true; \
if (first && (cond)) { \
first = false; \
ACTION(__VA_ARGS__); \
Expand All @@ -3507,8 +3509,9 @@ namespace zeroerr {

#define ZEROERR_LOG_FIRST_(n, cond, ACTION, ...) \
do { \
unsigned counter = n; \
if (n-- && (cond)) { \
static unsigned counter = n; \
if (counter && (cond)) { \
counter--; \
ACTION(__VA_ARGS__); \
} \
} while (0)
Expand Down Expand Up @@ -3605,24 +3608,24 @@ enum LogSeverity {

/**
* @brief LogInfo is a struct to store the meta data of the log message.
* @details LogInfo is a struct to store the meta data of the log message.
* @details LogInfo is a struct to store the meta data of the log message.
* It contains filename, function, message, category, line number, size, and severity.
* Those data is initialized when the first log message is created using a static
* local variable in the function where the log message is put.
*
*
* For example:
* void foo() {
* log("Hello, {name}!", "John");
* }
*
* The inner implementation could be considered as (not exactly
*
* The inner implementation could be considered as (not exactly
* since message is allocated from a pool):
* void foo() {
* static LogInfo log_info{
* __FILE__, __func__, "Hello, {name}!",
* ZEROERR_LOG_CATEGORY,
* __LINE__,
* sizeof("Hello, world!"),
* static LogInfo log_info{
* __FILE__, __func__, "Hello, {name}!",
* ZEROERR_LOG_CATEGORY,
* __LINE__,
* sizeof("Hello, world!"),
* LogSeverity::INFO_l);
* LogMessage* logdata = new LogMessageImpl<std::string>("John");
* logdata->info = &log_info;
Expand Down Expand Up @@ -3876,11 +3879,11 @@ class LogStream {
* The log message is structured as a tuple of the arguments in the inner
* implementation class LogMessageImpl. After the log message is created, it
* used type erasure to return a LogMessage pointer to the caller.
*
*
* The stored data type is determined by the to_store_type_t<T> template.
* For all the string type in raw pointer like const char* or char[],
* it will be converted to std::string.
* All reference type (including right value reference) will be converted
* All reference type (including right value reference) will be converted
* to the original type.
*/
template <typename... T>
Expand Down