I went for this solution in the end
#pragma once
// clang-format off
#define _logger_macro(_1, _2, _3, _4, _5, NAME, ...) NAME
#define logger_1(_1) loggerImpl(_1, #_1)
#define logger_2(_1, _2) loggerImpl(_1, #_1); logger_1(_2)
#define logger_3(_1, _2, _3) loggerImpl(_1, #_1); logger_2(_2, _3)
#define logger_4(_1, _2, _3, _4) loggerImpl(_1, #_1); logger_3(_2, _3, _4)
#define logger_5(_1, _2, _3, _4, _5) loggerImpl(_1, #_1); logger_4(_2, _3, _4, _5)
#define logger(...) \
_logger_macro(__VA_ARGS__, logger_5, logger_4, logger_3, logger_2, logger_1)(__VA_ARGS__);
// clang-format on
void logString(const std::string paramValue, const std::string paramName) {
std::string toLog =
paramValue == paramName ? paramValue : paramName + ": " + paramValue;
std::cout << toLog << std::endl;
}
void loggerImpl(const int paramValue, const char *paramName) {
logString(std::to_string(paramValue), paramName);
}
void loggerImpl(const float paramValue, const char *paramName) {
logString(std::to_string(paramValue), paramName);
}
void loggerImpl(const double paramValue, const char *paramName) {
logString(std::to_string(paramValue), paramName);
}
const std::string IS_TRUE = "true";
const std::string IS_FALSE = "false";
void loggerImpl(const bool paramValue, const char *paramName) {
logString(paramValue ? IS_TRUE : IS_FALSE, paramName);
}
void loggerImpl(const char *paramValue, const char *paramName) {
auto paramNameString = std::string(paramName);
logString(paramValue, paramNameString.substr(1, paramNameString.size() - 2));
}
void loggerImpl(const std::string paramValue, const char *paramName) {
logString(paramValue, paramName);
}