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); // a,h1,h2,my_dist are int and path is vector
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.
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.