Explanation of Template

Can someone please explain this template

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename
enable_if<sizeof dud(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge range(c i, c j) { return rge{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(…);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
ris << “(” << d.first << ", " << d.second << “)”;
}
sim dor(rge d) {
*this << “[”;
for (auto it = d.b; it != d.e; ++it)
*this << “, " + 2 * (it == d.b) << *it;
ris << “]”;
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(…) " [” << #VA_ARGS ": " << (VA_ARGS) << "] "

Can you copy and paste it as text? Running it through a pre-processor would make things clearer.

Edit: - and use Preformatted Text so that the forum software doesn’t mess it up XD

1 Like

The forum software has gobbled up a lot of the tokens, so I’ve had to re-construct it from the source image(!)

PSA: Please, please don’t post code as unformatted text XD

It looks like it’s designed to faciliate constructs like:

int main()
{
    vector<int> v = {1, 4, 5};
    debug() << v;

    const bool sausage = true;
    debug() << sausage;

    std::pair<string, int> somePair = { "pickle", 315 };
    debug() << somePair;
}

With the template added, this will expand (if the macro LOCAL is defined) to:

#include <iostream>
#include <vector>

using namespace std;

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; }
    template < class c > typename enable_if<sizeof dud<c>(0) != 1, debug&>::type operator<<(c i) { cerr << boolalpha << i; return * this; }
    template < class c > typename enable_if<sizeof dud<c>(0) == 1, debug&>::type operator<<(c i) { return * this << range(begin(i), end(i)); }
    template < class c, class b > debug & operator <<(pair < b, c > d) {
        return * this << "(" << d.first << ", " << d.second << ")";
    }
    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 << "]";
    }
    
};

int main()
{
    vector<int> v = {1, 4, 5};
    debug() << v;

    const bool sausage = true;
    debug() << sausage;

    std::pair<string, int> somePair = { "pickle", 315 };
    debug() << somePair;
}

There’s some type-traits stuff in there that special-cases the case where we try to print containers (like v above).

Nothing particularly magical - let me know if you want further details :slight_smile:

5 Likes

Yeah , i got it . Thanks

You can check this Warsaw debug template dissection - Codeforces

4 Likes

Actually , i the code that i posted here is of the same link . But , i did not understand properly . Thanks btw!!