Skip to content

Instantly share code, notes, and snippets.

@craftablescience
Last active September 8, 2023 20:00
Show Gist options
  • Save craftablescience/23ca6992667b28cf80c9d73e41fb88ba to your computer and use it in GitHub Desktop.
Save craftablescience/23ca6992667b28cf80c9d73e41fb88ba to your computer and use it in GitHub Desktop.
Debug printer for all C types, C arrays (1D and 2D), standard container types, and std::pair.
#pragma once
#include <iostream>
#include <string>
template<typename T, std::enable_if_t<!std::is_class_v<T> || std::is_same_v<T, std::string>, bool> = true> std::string debug_internal(const T& value, bool printPrefix = true) {
std::string prefix;
if constexpr (std::is_pointer_v<T>) {
if (printPrefix) prefix = "-> ";
if (!value) return prefix + "NULL";
if constexpr (std::is_convertible_v<T, std::string>) return prefix + '\"' + value + '\"';
else return prefix + debug_internal(*value, false);
} else {
if (printPrefix) prefix = "= ";
if constexpr (std::is_same_v<T, char>) {
if (!value) return prefix + "NULL";
return prefix + '\'' + value + '\'';
} else if constexpr (std::is_same_v<T, std::string> || std::is_convertible_v<T, std::string>) return prefix + '\"' + value + '\"';
else if constexpr (std::is_arithmetic_v<T>) return prefix + std::to_string(value);
else return "cannot be stringified??";
}
}
template<typename T, int N> std::string debug_internal(const T(&value)[N], bool printPrefix = true) {
std::string out = std::string{printPrefix ? "-> " : ""} + '[';
for (int i = 0; i < N; i++) out += debug_internal(value[i], false) + ", ";
return out.substr(0, out.length() - 2) + ']';
}
template<typename T, int N, int O> std::string debug_internal(const T(&value)[N][O], bool printPrefix = true) {
std::string out = std::string{printPrefix ? "->\n" : ""} + " [";
for (int i = 0; i < N; i++) out += (i > 0 ? " " : "") + debug_internal(value[i], false) + ",\n";
return out.substr(0, out.length() - 2) + ']';
}
template<typename T, typename C = typename T::value_type, std::enable_if_t<!std::is_same_v<T, std::string>, bool> = true> std::string debug_internal(const T& value, bool printPrefix = true) {
std::string out = std::string{printPrefix ? "= " : ""} + '[';
for (const auto& item : value) out += debug_internal(item, false) + ", ";
return out.substr(0, out.length() - (value.size() > 0) * 2) + ']';
}
template<typename T, typename F = decltype(T::first), typename S = decltype(T::second)> std::string debug_internal(const T& value, bool printPrefix = true) {
return std::string{printPrefix ? "= " : ""} + '<' + debug_internal(value.first, false) + ", " + debug_internal(value.second, false) + '>';
}
#define dbg(var) std::cout << #var << ' ' << debug_internal(var, true) << std::endl
#include "dbg.h"
#include <vector>
#include <utility>
int main() {
const char* string = "one";
dbg(string);
const char charArray[] = "two";
dbg(charArray);
int number = 1;
dbg(number);
std::int64_t biggestNumber = 24135932545343339;
dbg(biggestNumber);
char character = 'h';
dbg(character);
int intArray1D[] = {1, 2, 3};
dbg(intArray1D);
int intArray2D[][3] {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
};
dbg(intArray2D);
long long longNumber = 15LL;
dbg(longNumber);
long long* pLongNumber = &longNumber;
dbg(pLongNumber);
std::vector<int> emptyList(0,0);
dbg(emptyList);
std::vector<int> list(4, 42);
dbg(list);
std::pair<int, char> pair{24, 'Y'};
dbg(pair);
std::vector<std::pair<char, std::vector<std::string>>> recursiveList {
{'A', {"Hello", "World"}},
{'B', {"Foo", "Bar", "Baz"}},
};
dbg(recursiveList);
}
string -> "one"
charArray -> ['t', 'w', 'o', NULL]
number = 1
biggestNumber = 24135932545343339
character = 'h'
intArray1D -> [1, 2, 3]
intArray2D ->
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
longNumber = 15
pLongNumber -> 15
emptyList = []
list = [42, 42, 42, 42]
pair = <24, 'Y'>
recursiveList = [<'A', ["Hello", "World"]>, <'B', ["Foo", "Bar", "Baz"]>]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment