sharkdp / dbg-macro

A dbg(…) macro for C++
MIT License
2.97k stars 257 forks source link

debug print on some condition #115

Closed district10 closed 2 years ago

district10 commented 3 years ago

I'd like to configure dbg to print on some condition. dbg is a macro so these are not what I'm looking for:

#include "dbg.h"

struct MyStruct {
    bool verbose;
    MyStruct(bool verbose) : verbose(verbose) {}
    void demo() const {
        verbose_print("one", 2, std::vector<int>{3, 4});
    }

private:
    template <typename T, typename... Ts>
    void verbose_print(T&& head, Ts&&... tail) const {
        if (!verbose) {
            return;
        }
        dbg(head);
        verbose_print(std::forward<Ts>(tail)...);
    }
    template <typename T>
    void verbose_print(T&& head) const {
        if (!verbose) {
            return;
        }
        dbg(head);
    }
};

int main() {
    MyStruct(true).demo();
    MyStruct(false).demo();
    return 0;
}

// [test.cpp:16 (verbose_print)] one
// [test.cpp:16 (verbose_print)] head = 2 (int&&)
// [test.cpp:24 (verbose_print)] head = {3, 4} (std::vector<int>&&)

Related?: https://github.com/sharkdp/dbg-macro/issues/109

Is it possible to expand the macro on some condition? So I can use it like:

dbg_if(verbose, "one", 2, std::vector<int>{3, 4});

Macros are not expanded at running time, so... Is there any other solutions?

Thank you guys.

sharkdp commented 3 years ago

Thank you for the feedback.

This is not supported right now (and I'm not sure if I want to integrate it). But it might be possible to write a macro on your own, similar to:

#define dbg_if(condition, arg)    \
  if (condition) {                \
    dbg(arg);                     \
  }

... but with multiple args.

district10 commented 3 years ago

Thank you for the feedback.

This is not supported right now (and I'm not sure if I want to integrate it). But it might be possible to write a macro on your own, similar to:

#define dbg_if(condition, arg)    \
  if (condition) {                \
    dbg(arg);                     \
  }

... but with multiple args.

That's simply and smart. It works for me.

Let's just forget about multiple args for now.

(That simple?... Never came to my mind...)

district10 commented 3 years ago

Check this out:

#define DBG_MACRO_NO_WARNING
#include "dbg.h"

#define dbg_if_2(condition, arg1) if (condition) { dbg(arg1); }
#define dbg_if_3(condition, arg1, arg2) if (condition) { dbg(arg1, arg2); }
#define dbg_if_4(condition, arg1, arg2, arg3) if (condition) { dbg(arg1, arg2, arg3); }
// https://stackoverflow.com/questions/11761703/overloading-macro-on-number-of-arguments
#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define dbg_if(...) GET_MACRO(__VA_ARGS__, dbg_if_4, dbg_if_3, dbg_if_2, UNUSED)(__VA_ARGS__)

int main()
{
    std::vector<double> vecs{1, 2, 3};
    for (bool verbose: std::vector<bool>{true, false}) {
        dbg("--------------");
        dbg(verbose);
        dbg_if(verbose, vecs);
        dbg_if(verbose, vecs, vecs[0]);
        dbg_if(verbose, vecs, vecs[0], verbose);
    }
    dbg("--------------");
}

Output:

[prog.cc:15 (main)] --------------
[prog.cc:16 (main)] verbose = true (bool)
[prog.cc:17 (main)] vecs = {1, 2, 3} (std::vector<double>)
[prog.cc:18 (main)] vecs = {1, 2, 3} (std::vector<double>)
[prog.cc:18 (main)] vecs[0] = 1 (double&)
[prog.cc:19 (main)] vecs = {1, 2, 3} (std::vector<double>)
[prog.cc:19 (main)] vecs[0] = 1 (double&)
[prog.cc:19 (main)] verbose = true (bool)
[prog.cc:15 (main)] --------------
[prog.cc:16 (main)] verbose = false (bool)
[prog.cc:21 (main)] --------------

wanbox link: https://wandbox.org/permlink/PCPQ5xMfIFTPIRT9