Many times while debugging in contests, to trace the elements I use multiple functions like following,
It's good if I can trace all using one method, I was looking for one single function/method for printing variables, vectors, etc.
Watching Errichto streams and this tweet during ICPC live stream, I got interested in this template but couldn't understand much of this, I wanted to use this template, know how to use, but don't understand why it works, and I try not to put things that I don’t understand in my template, Can you please help me in understanding this
We can generally use this like this
debug() << imie(c * 2) imie(min(a, b)) imie(a != b);
debug() << "add" imie(i) imie(A) imie(diff);
debug() << imie(V); // V is a vector
debug() << imie(a) imie(h1) imie(h2) imie(my_dist) imie(path) imie(vertices); // int a,h1,h2; vector path;
debug() << "Zlaczacz::Ogarnij(" imie(a) imie(b) ") = " << res; // pair<vector<int>, vector<int>> res; int a,b;
So I have elaborated code and it resulted in the following
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
/*sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);*/
template < class c > struct rge { c b, e; };
template < class c > rge<c> range(c i, c j) { return rge<c>{i, j}; }
template < class c > auto dud(c* x) -> decltype(cerr << *x, 0);
template < class c > char dud(...);
struct debug {
~debug() { cerr << endl; }
//eni(!=) cerr << boolalpha << i; ris; } Part 1
template < class c > typename \
enable_if<sizeof dud<c>(0) != 1, debug&>::type operator<<(c i) {
cerr << boolalpha << i;
return * this;
}
//eni(==) ris << range(begin(i), end(i)); } Part 2
template < class c > typename \
enable_if<sizeof dud<c>(0) == 1, debug&>::type operator<<(c i) {
return * this << range(begin(i), end(i));
}
/*sim, class b dor(pair < b, c > d) { Part 3
ris << "(" << d.first << ", " << d.second << ")";
}*/
template < class c, class b > debug & operator << (pair < b, c > d) {
return * this << "(" << d.first << ", " << d.second << ")";
}
/*sim dor(rge<c> d) { Part 4
*this << "[";
for (auto it = d.b; it != d.e; ++it)
*this << ", " + 2 * (it == d.b) << *it;
ris << "]";
}*/
template < class c > debug & operator <<(rge<c> d) {
*this << "[";
for (auto it = d.b; it != d.e; ++it)
*this << ", " + 2 * (it == d.b) << *it;
return * this << "]";
}
}
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
std::boolalpha
is an I/O manipulator, it causes bool values to display as true or false. decltype
inspects the declared type of an entity or the type and value category of expression.
When the macro is invoked, all the tokens in its argument list after the last named argument (this macro has none), including any commas, become the variable argument. This sequence of tokens replaces the identifier __VA_ARGS__
in the macro body wherever it appears. You may use the #
and ##
operators to stringify the variable argument or to paste its leading or trailing token with another token — Ref
template< bool B, class T = void >
struct enable_if;
/* If B is true, std::enable_if has a public member typedef type, equal to T; otherwise, there is no member typedef. */
template <typename T>
struct enable_if<true, T> {
typedef T type;
};
Can someone please explain what eni(x)
, dud
does? and how does eni
relate to Part 1 and Part 2? I didn't understand eni(x)
and dud
.
How rge
is used in range
?
I understand that Part 4 is to iterate through containers, is Part 3 for pairs?
Thank you in advance.