Warsaw debug template dissection

Revision en2, by RNR, 2019-06-21 09:23:41

Many times while debugging in contests, to trace the elements I use multiple functions like following,

Code

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

Original code

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.

Tags debugging, debug, warsaw, c++ template

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en3 English RNR 2019-06-21 11:34:48 611 Tiny change: 'ther token. You can read more [here](https://' -> 'ther token [Ref](https://'
en2 English RNR 2019-06-21 09:23:41 75
en1 English RNR 2019-06-20 18:49:10 5039 Initial revision (published)