Search code examples
c++variadic-templates

How to turn Variadic Templates into multiple single templates?(C++ Competitive Programming Debugging Template)


My debugging template is:

#define ts to_string 
string ts(char c) { return string(1, c); }
string ts(bool b) { return b ? "true" : "false"; }
string ts(const char* s) { return (string)s; }
string ts(string s) { return s; }
template<class A> string ts(complex<A> c) { 
    stringstream ss; ss << c; return ss.str(); }
string ts(vector<bool> v) { 
    string res = "{"; for(int i = 0; i < si(v); ++i) res += char('0' + v[i]);
    res += "}"; return res; }
template<size_t SZ> string ts(bitset<SZ> b) {
    string res = ""; for(int i = 0; i < SZ; ++i) res += char('0' + b[i]);
    return res; }
template<class A, class B> string ts(pair<A,B> p);
template<class T> string ts(T v) { // containers with begin(), end()
    bool fst = 1; string res = "{";
    for(const auto& x: v) {
        if (!fst) res += ", ";
        fst = 0; res += ts(x);
    }
    res += "}"; return res;
}
template<class A, class B> string ts(pair<A,B> p) {
    return "(" + ts(p.f) + ", " + ts(p.s) + ")"; }

void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
    cerr << ts(h); if (sizeof...(t)) cerr << ", ";
    DBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 0
#endif

When I type

dbg(a, n);

where 'a' is the vector name and n is the size of the vector. 'a' contains the following {1, 2, 3, 4, 5} and n = 5

it prints

[a, n]: [{1, 2, 3, 4, 5}, 5]

but I want it to print

[a]: [{1, 2, 3, 4, 5}]
[n]: [5]

without having to type

dbg(a);
dbg(n);

Is there any way to do this?


Solution

  • Codeforces community has helped me and told me the correct solution.

    #define ts to_string
    string ts(char c) { return string(1, c); }
    string ts(bool b) { return b ? "true" : "false"; }
    string ts(const char* s) { return (string)s; }
    string ts(string s) { return s; }
    template<class A> string ts(complex<A> c) { 
        stringstream ss; ss << c; return ss.str(); }
    string ts(vector<bool> v) { 
        string res = "{"; for(int i = 0; i < si(v); ++i) res += char('0' + v[i]);
        res += "}"; return res; }
    template<size_t SZ> string ts(bitset<SZ> b) {
        string res = ""; for(int i = 0; i < SZ; ++i) res += char('0' + b[i]);
        return res; }
    template<class A, class B> string ts(pair<A,B> p);
    template<class T> string ts(T v) { // containers with begin(), end()
        bool fst = 1; string res = "{";
        for (const auto& x: v) {
            if (!fst) res += ", ";
            fst = 0; res += ts(x);
        }
        res += "}"; return res;
    }
    template<class A, class B> string ts(pair<A,B> p) {
        return "(" + ts(p.f) + ", " + ts(p.s) + ")"; }
     
    // DEBUG
    void DBG(string names) { string s = names; }
    template<class H, class... T> void DBG(string names, H h, T... t) {
        auto pos = names.find(',');
        auto first_name = names.substr(0, pos);
        auto rest = names.substr(pos+1);
        // Strip space at the beginning
        while(rest.front() == ' '){
            rest = rest.substr(1);
        }
        cerr << "[" << first_name << "]: [" << ts(h) << "]" << nl;
        DBG(rest, t...);
    }
    #ifdef LOCAL
    #define dbg(...) DBG(#__VA_ARGS__, __VA_ARGS__)
    #else
    #define dbg(...) 0
    #endif
    void EDBG() { cerr << "]" << endl; }
    template<class H, class... T> void EDBG(H h, T... t) {
        cerr << ts(h); if (sizeof...(t)) cerr << ", ";
        EDBG(t...); }
    #ifdef LOCAL // compile with -DLOCAL
    #define edbg(...) cerr << "[" << #__VA_ARGS__ << "]: [", EDBG(__VA_ARGS__)
    #else
    #define edbg(...) 0
    #endif
    

    the macro

    edbg
    

    does not do it seperately so

    edbg(a, n);
    

    will output

    edbg(a, n);
    

    Whereas

    dbg(a, n);
    

    will output

    dbg(a);
    dbg(n);