Warsaw debug template dissection

Revision en3, by myHandle, 2019-06-21 11:34:48

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); // 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.

Tags debugging, debug, warsaw, c++ template

History

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