Last active
August 29, 2015 14:10
-
-
Save 1995eaton/868371393e50a3c53d1a to your computer and use it in GitHub Desktop.
C++ logging functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef LOG_H | |
#define LOG_H | |
#include <iostream> | |
#include <iomanip> | |
#include <sstream> | |
#include <cctype> | |
template <typename T> | |
struct TYPE; | |
#define typeof(E) TYPE<decltype(E)>(); | |
template <typename T> | |
struct is_iterable { | |
template <typename U> | |
static char test(typename U::iterator*); | |
template <typename U> | |
static int test(...); | |
static constexpr bool value = sizeof test<T>(0) == 1; | |
}; | |
template <typename A, typename B> | |
std::string STR(const std::pair<A, B>& first); | |
template <typename T, | |
typename std::enable_if<!is_iterable<T>::value>::type* = nullptr> | |
std::string STR(const T& first) { | |
std::ostringstream result; | |
result << first; | |
return result.str(); | |
} | |
std::string STR(const char& first) { | |
std::string result = "'"; | |
if (isprint(first)) { | |
result += first; | |
} else { | |
result += "\\x"; | |
std::ostringstream hex; | |
hex << std::setw(8) << std::setfill('0') << | |
std::hex << static_cast<int>(first); | |
result += hex.str().substr(6, 2); | |
} | |
result += "'"; | |
return result; | |
} | |
template <typename T> | |
std::string STR(const std::basic_string<T>& first) { | |
return first; | |
} | |
std::string STR(const bool& first) { | |
return first ? "true" : "false"; | |
} | |
template <typename T, | |
typename std::enable_if<is_iterable<T>::value>::type* = nullptr> | |
std::string STR(const T& first) { | |
std::ostringstream result; | |
result << '{'; | |
for (const auto& it: first) { | |
result << STR(it) << ", "; | |
} | |
std::string rstring = result.str(); | |
if (rstring.length() > 2 && | |
rstring.back() == ' ' && | |
rstring[rstring.length() - 2] == ',') { | |
rstring.pop_back(); | |
rstring.pop_back(); | |
} | |
return rstring + '}'; | |
} | |
template <typename T> | |
struct SIZE; | |
template <typename T, size_t N> | |
struct SIZE<T[N]> { | |
static constexpr size_t value = N; | |
}; | |
template <typename T, size_t N> | |
std::string STR(const T (&first)[N]) { | |
std::ostringstream result; | |
result << '{'; | |
for (size_t i = 0; i < N; i++) { | |
result << STR(first[i]) << ", "; | |
} | |
std::string rstring = result.str(); | |
if (rstring.length() > 2 && | |
rstring.back() == ' ' && | |
rstring[rstring.length() - 2] == ',') { | |
rstring.pop_back(); | |
rstring.pop_back(); | |
} | |
return rstring + '}'; | |
} | |
template <typename A, typename B> | |
std::string STR(const std::pair<A, B>& first) { | |
std::ostringstream result; | |
result << STR(first.first); | |
result << ": "; | |
result << STR(first.second); | |
return result.str(); | |
} | |
void LOG() { | |
std::cout << std::endl; | |
} | |
template <typename T> | |
void LOG(const T& first) { | |
std::cout << STR(first) << std::endl; | |
} | |
template <typename T, typename ...U> | |
void LOG(const T& first, const U&... rest) { | |
std::cout << STR(first) << ' '; | |
LOG(rest...); | |
} | |
void LOGF(const std::string& fmt) { | |
LOG(fmt); | |
} | |
template <typename T> | |
void LOGF(std::string fmt, const T& first) { | |
size_t index = fmt.find("{}"); | |
if (index != std::string::npos) | |
fmt.replace(index, 2, STR(first)); | |
else | |
fmt += " " + STR(first); | |
LOG(fmt); | |
} | |
template <typename T, typename ...U> | |
void LOGF(std::string fmt, const T& first, const U&... rest) { | |
size_t index = fmt.find("{}"); | |
if (index != std::string::npos) | |
fmt.replace(index, 2, STR(first)); | |
else | |
fmt += " " + STR(first); | |
LOGF(fmt, rest...); | |
} | |
template <typename ...T> | |
void print(T&&... args) { | |
LOG(std::forward<T>(args)...); | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment