diff --git a/debug.h b/debug.h new file mode 100644 index 0000000..bf23ce1 --- /dev/null +++ b/debug.h @@ -0,0 +1,112 @@ +#include +namespace __DEBUG_UTIL__ +{ + using namespace std; + template + concept is_iterable = requires(T &&x) { begin(x); } && + !is_same_v, string>; + void print(const char *x) { cerr << x; } + void print(char x) { cerr << "\'" << x << "\'"; } + void print(bool x) { cerr << (x ? "T" : "F"); } + void print(string x) { cerr << "\"" << x << "\""; } + void print(vector &v) + { /* Overloaded this because stl optimizes vector by using + _Bit_reference instead of bool to conserve space. */ + int f = 0; + cerr << '{'; + for (auto &&i : v) + cerr << (f++ ? "," : "") << (i ? "T" : "F"); + cerr << "}"; + } + template + void print(T &&x) + { + if constexpr (is_iterable) + if (size(x) && is_iterable) + { /* Iterable inside Iterable */ + int f = 0; + cerr << "\n~~~~~\n"; + for (auto &&i : x) + { + cerr << setw(2) << left << f++, print(i), cerr << "\n"; + } + cerr << "~~~~~\n"; + } + else + { /* Normal Iterable */ + int f = 0; + cerr << "{"; + for (auto &&i : x) + cerr << (f++ ? "," : ""), print(i); + cerr << "}"; + } + else if constexpr (requires { x.pop(); }) /* Stacks, Priority Queues, Queues */ + { + auto temp = x; + int f = 0; + cerr << "{"; + if constexpr (requires { x.top(); }) + while (!temp.empty()) + cerr << (f++ ? "," : ""), print(temp.top()), temp.pop(); + else + while (!temp.empty()) + cerr << (f++ ? "," : ""), print(temp.front()), temp.pop(); + cerr << "}"; + } + else if constexpr (requires { x.first; x.second; }) /* Pair */ + { + cerr << '(', print(x.first), cerr << ',', print(x.second), cerr << ')'; + } + else if constexpr (requires { get<0>(x); }) /* Tuple */ + { + int f = 0; + cerr << '(', apply([&f](auto... args) + { ((cerr << (f++ ? "," : ""), print(args)), ...); }, + x); + cerr << ')'; + } + else + cerr << x; + } + template + void printer(const char *names, T &&head, V &&...tail) + { + int i = 0; + for (size_t bracket = 0; names[i] != '\0' and (names[i] != ',' or bracket != 0); i++) + if (names[i] == '(' or names[i] == '<' or names[i] == '{') + bracket++; + else if (names[i] == ')' or names[i] == '>' or names[i] == '}') + bracket--; + cerr.write(names, i) << " = "; + print(head); + if constexpr (sizeof...(tail)) + cerr << " ||", printer(names + i + 1, tail...); + else + cerr << "]\n"; + } + template + void printerArr(const char *names, T arr[], size_t N, V... tail) + { + size_t i = 0; + for (; names[i] and names[i] != ','; i++) + cerr << names[i]; + for (i++; names[i] and names[i] != ','; i++) + ; + cerr << " = {"; + for (size_t ind = 0; ind < N; ind++) + cerr << (ind ? "," : ""), print(arr[ind]); + cerr << "}"; + if constexpr (sizeof...(tail)) + cerr << " ||", printerArr(names + i + 1, tail...); + else + cerr << "]\n"; + } + +} +#ifdef ONLINE_JUDGE +#define dbg(...) +#define dbgArr(...) +#else +#define dbg(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printer(#__VA_ARGS__, __VA_ARGS__) +#define dbgArr(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printerArr(#__VA_ARGS__, __VA_ARGS__) +#endif \ No newline at end of file