I am designing a logger. I'll format for it. I made a design that I would predetermine the format string and then keep this data in a tuple and print it to the log.
The code below is working now, but I want it to work in the parts I commented out. So, according to the default arguments I set, I want it to use the default argument if no argument is given.
NOTE: I want these processes to be at compile time.
#include <iostream>
#include <tuple>
#include <memory>
#include <type_traits>
class MyLogger {
public:
template<typename... Args>
void Log(const char* format, Args... args) {
printf(format, args...);
printf("\n");
}
};
static inline std::unique_ptr<MyLogger> logger = std::make_unique<MyLogger>();
template<typename FMT, typename... Args>
struct LogLineDef {
LogLineDef(Args... args) : values(args...) {}
std::tuple<Args...> values;
};
constexpr char FMT1[] = "A:%d, B:%d, C:%d, D:%f ";
using L1 = LogLineDef<std::integral_constant<const char*, FMT1>, int, int, int, float>;
template<typename FMT, typename... Args>
void log_helper(const char* message, const LogLineDef<FMT, Args...>& logger_line_def) {
std::apply([message](const auto&... args) {
logger->Log((FMT::value + std::string(message)).c_str(), args...);
}, logger_line_def.values);
}
#define LOG(logger_line_def, message, ...) log_helper(message, logger_line_def, ##__VA_ARGS__)
int main() {
LOG(L1(1, 2, 3, 4.f), "error");
//LOG(L1(1, 2, 3), "error"); // should be legal according to default value
//LOG(L1(1, 2), "error"); // should be legal according to default value
}