Giter Club home page Giter Club logo

dbg-macro's People

Contributors

baltoli avatar derekcresswell avatar fuchengjie avatar harry-chen avatar hmenke avatar mrhate avatar sharkdp avatar shikchen avatar shilangyu avatar stackoverflowexcept1on avatar studoot avatar winwinashwin avatar yarikth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dbg-macro's Issues

it does't android ndk

I use dbg.h to print JNI log, but there are very many errors, can you let it support Android NDK?
my code:

#ifdef __ANDROID__
#include <android/log.h>
#endif
   output << std::endl;
    std::cerr << output.str();
    
#ifdef __ANDROID__
__android_log_print(ANDROID_LOG_INFO,  "dbg",  "%s\n", output.str().c_str());
#endif

    return std::forward<T>(value);

use in Qt

I would like to use this awesome macro in Qt. However, qt metatypes or QVariant use QDataStream as the stream operator.
Is there any idea to handle that?

Print integral types as bit sizes instead of standard types

Hello !

Another idea for improvements:

image

As for now, integral types are shown as int, unsigned int, etc

An idea is to print them as uint8, int8, uint16, etc

This is because an int does represent the size of the integral only for the platform it currently run.

I think a lot of developers do not use standard types (int, char, ...) but typedefs types (uint32_t, uint8_t, ...) just like me!

I think this is just a matter of updating theses lines with proper types even if there could be a better more generic way:
image

If you agree to this feature and you are not available, it will be my pleasure to provide a PR!

How about output "{?}" string for unknown types instead of failing with static assert?

I trying to debug highly templated code. And some of the debugged values have ostream overloads, some don't have. The library force to write ostream overloads for every type or it give up to compile. I suggest altering pretty_print false_type to output some fake but recognizable value like doctest does.

template <typename T>
inline void pretty_print(std::ostream& stream, const T&, std::false_type) {
  stream << "{?}";
}

This allows using the library more convenient way and the user has pretty type information anyway even they don't have the value printed. And if user do want to see the value, they have to support ostream operator anyway.

Add contributing guidelines

With the recent changes to tests I believe it would be very beneficial to add some guidelines to this repo for things like tests and documentation.
@sharkdp this should likely be your responsibility. It should make the PR process in this repo more stream lined.
We should have :

  • Test guidelines. How many tests should be added and to which files.
  • Documentation standards. What should be inline comments and what should be added to a wiki.
  • Perhaps an issue / PR template.

GCC 4.x error: no matching function for call to ‘size(const char* const&)’

So I used 'dbg.h' in the past in the same project and had no issues building but now I am getting the following error:

/usr/include/dbg.h: In substitution of ‘template<class T> using detect_size_t = decltype (dbg::detail::{anonymous}::size(declval<T>())) [with T = const char* const&]’:                                                                                                         
/usr/include/dbg.h:283:27:   required from ‘struct dbg::detail_detector::detector<dbg::detail_detector::nonesuch, void, dbg::detail::det
ect_size_t, const char* const&>’                                                                                                        
/usr/include/dbg.h:290:68:   required by substitution of ‘template<template<class ...> class Op, class ... Args> using is_detected = typ
ename dbg::detail_detector::detector<dbg::detail_detector::nonesuch, void, Op, Args ...>::value_t [with Op = dbg::detail::detect_size_t;
 Args = {const char* const&}]’                                                                                                          
/usr/include/dbg.h:324:43:   required from ‘constexpr const bool dbg::detail::is_container<const char* const&>::value’                  
/usr/include/dbg.h:363:32:   required by substitution of ‘template<class T> typename std::enable_if<((! dbg::detail::is_container<const T&>::value) && (! std::is_enum<_Tp>::value)), bool>::type dbg::pretty_print(std::ostream&, const T&) [with T = const char*]’            
/usr/include/dbg.h:421:72:   required from here                                                                                         /usr/include/dbg.h:318:62: error: no matching function for call to ‘size(const char* const&)’                                           
 using detect_size_t = decltype(detail::size(std::declval<T>()));    

I installed the header file as suggested in /usr/include/dbg.h.

Allow specifying the output stream

When using RapidCheck, I'd like the option to write to RC_LOG() instead of std::cerr:

Since the property function may be called many times, using classic debugging techniques such as printing to stdout or stderr can prove confusing. The RC_LOG macro provides a better way to log information during the execution of a test case. Information logged this way will only be printed on failure after the minimal test case has been found.

CMake: install export targets

We should probably add a install(EXPORT …) command in CMakeLists.txt for people that want to use dbg-macro via CMake.

Better function-name information

We currently use __func__ to add the function name annotation in the output. However, the output for class methods or lambdas is not optimal:

class user_defined_class {
 public:
  void some_method(int x) {
    dbg(x);
  }
};

// ...

user_defined_class{}.some_method(42);

[](int x) {
  dbg("called from within a lambda!");
  return x;
}(42);

prints:

[..acro/tests/tests.cpp:34 (some_method)] x = 42 (int)
[..acro/tests/tests.cpp:138 (operator())] called from within a lambda!

If we would use __PRETTY_FUNCTION__ instead, we could potentially turn some_method into user_defined_class::some_method and operator() into main()::<lambda(int)>. This would, however, require us to post-process the __PRETTY_FUNCTION__ string and remove return type, argument names, etc.

See also: https://stackoverflow.com/a/29856690/704831

<ios> and <iomanip> flags

Hello!

This project is very great, thank you!

I often need to print values as hexadecimal, and bonus point as binary. It would be nice if this library support it.

Maybe dbg(std::hex, number)? This does break the implicit rull that arguments are all "dbged" but it could work.
Maybe dbg::dbg(dbg::hex(number))?

If you do not have time, I can PR this feature if you are ok on the concept and the way of doing it!

EDIT: maybe I missed the already-existing feature to print as hexadecimal!

Idea: add type information?

We could potentially use typeid(…).name() to add type information about the debugged value. This could be really helpful if used somewhere inside expressions where the type is not completely obvious.

We would have to find a cross-compiler way to demangle the typeid(…).name() string...

Broken output of containers

See example below.
https://godbolt.org/z/vnxaqq

#include <dbg.h>

int main()
{
    std::vector<std::pair<std::string, int>> container = {
        {"30+2", 32}, {"30-2", 28}, {"30*2", 60}
    };
    dbg(container);
}

Here we have a vector of pairs of strings. Despite the library has pretty_print overloads for std::pair, std::string, and container they don't fully work with each other. It seems that the reason is the fact, that pretty_print overloads for std::pair and std::string are defined just after container overload and thus they aren't visible from pretty_print overload for containers.

A possible solution is adding declarations for all the pretty_print overloads before their definitions. For e.g. in my example, adding declarations for pair and string overloads before container overload fixes the problem.

inline bool pretty_print(std::ostream& stream, const std::string& value);

template <typename T1, typename T2>
inline bool pretty_print(std::ostream& stream, const std::pair<T1, T2>& value);



template <typename Container>
inline typename std::enable_if<detail::is_container<const Container&>::value,
                               bool>::type
pretty_print(std::ostream& stream, const Container& value) {

Add output level

Could you please add this feature? So that we can easily classify the debug level, e.g., INFO, WARNING, ERROR. Thanks!

[help]dbg with lambda

As you may know, some times dbg expression may be an proc of lamda showing as below

int factorial(int n) {
  if (dbg(n <= 1)) {
    return dbg(1);
  } else {
    return dbg([&](){ printf("%d\n", n);
      return n * factorial(n - 1);
    }());
  }
}

but compiler report an error

main.cpp:9:16: error: lambda expression in an unevaluated operand
    return dbg([&](){

so I make a compromise to make compiler happy

int factorial(int n) {
  if (dbg(n <= 1)) {
    return dbg(1);
  } else {
    auto a = [&](){
      printf("%d\n", n);
      return n * factorial(n - 1);
    };
    return dbg(a());
  }
}

Is there a solution to avoid the stack variable when DBG_MACRO_DISABLE is true

Better compile-time error messages

If a user calls dbg(x) with a value x of unsupported type X, the compiler prints a huge error message due to the missing operator<< overload:

error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const X’)
   stream << value;
   ~~~~~~~^~~~~~~~

[… a lot of lines suggesting alternative overloads …]

If we could detect that dbg(…) is called with an unsupported type (*), we could potentially print a nicer error message.

(*) The check for whether or not a type is "supported" is actually a bit involved: it would require two stages: (1) check if X is one of the "natively" supported types like std::optional<T> or any container type (2) check if X has an operator<< overload for ostream.

Add binary printing

Seeing as we can print decimal, octal, and hexadecimal it seems only right to include binary as it has it's uses as well.
I see we are using the std::setbase to convert our numbers which does not support binary (why though? Come on c++). There needs to be a bit of talk before we add this though.

Two ways to go about this :

  1. Not use std::setbase and use a more universal converter. Keeps everything more uniform but likely will be larger.
  2. Add a one off value.base == 2 inside of the pretty_print for these. Less uniform but likely easier.
  3. Add a seperate pretty_print for dbg::bin to keep everything more separate.

I've played around and made a prototype using number 2 and a decToBin function and got it printing out pretty well. I'll pretty it up and make it into a PR if we want to go this route.
It also would not be difficult to switch to a number 3 from here.

Let me know of any other ideas / options : )

Is it possible to allow variadic template expansion?

I'd like to be able to write

    dbg(args...);

So far it breaks when the macro is expanded. The workaround might be to create a tuple from a variadic template like this:

    std::tuple<ARGS...> input{args...};
    dbg(input);

But it adds some unwanted output regarding the input type (std::tuple<...), and has other issues (see #102)

debug print on some condition

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?: #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.

Reverse typedefs

Branching off #5 that added type information, some of the types are not very pretty, e.g. std::__cxx11::basic_string<char> when most people would like to see std::string. It would be nice to be able to define "reverse typedefs" that transform fully-qualified underlying type names into pretty type aliases, and to include batteries for some of the most common instances, e.g. std::string and std::vector.

Add support for simple structs?

It would be cool to somehow add support for simple structs/classes like

struct CustomDatatype {
  int field1;
  std::string field2;
};

//

CustomDatatype c{42, "hello"};
dbg(c);

We would somehow have to iterate over all members... without modifying to original struct definition. Not sure if this is possible in C++ (without reflection).

Unable to print std::string when printing multiple variables.

The following fails to print the content of t->message

  struct Test{
    std::string message;
  };

  std::shared_ptr<Test> t(new Test);
  t->message = "hello";
  dbg("Request from", t->message, 23);

expected output:

[..xxx.cpp:24 (helloWorld)] "Request from", t->message = "hello" (std::string), 23 = 23 (int)

actual output:

[..xxx.cpp:24 (helloWorld)] "Request from", t->message, 23 = 23 (int)

Add support for empty "dbg()" calls.

The dbg-macro call includes file, line and function information anyway, so empty

dbg();

calls can be helpful as well (instead of a dummy dbg("this is executed") call).

Support for enums?

Enums are currently not supported (unless the user has defined an operator<< overload for ostream).

We could potentially implement support for enums if we:

  • use std::is_enum<E> to add a specialization for enums (similar to containers)
  • cast the value to std::underlying_type<E>::type and print that.

If we decide to do this, we should probably only use the overload if no custom operator<< is defined for that type.

Support for all kinds of containers

Use a little bit of type_traits magic to make debugging of all container types possible.

For example, use std::enable_if to use the container-specialized overload if a begin, end (and size) function exists.

Put tests behind feature flag in CMakeLists.txt

I'm using dbg-macro in my project by using the CMake add_subdirectory command. This brings in not just the library, but also the test executables. They don't get built, but the contained tests get added to CTest's list of tests to run, which means that CTest fails.

Looking at another header-only library that I use, I see that it uses a feature flag to exclude the tests when not wanted. This could be done with dbg-macro by wrapping lines 10-19 in:

if (DBG_MACRO_ENABLE_TESTS)
    :         :        :
(existing lines 10-19 here)
    :         :        :
endif()

I'm quite happy to create a pull-request for it...

Provide an optional timestamp?

How about providing a macro name to switch whether to print timestamp before each line?

just like:

#define DBG_MACRO_TIMESTAMP
#include <dbg.h>

then

(13:18:53)[demo.cpp:34 (main)] test_int = 42 (int)

Is support it for android ?

I have tried to use the dbg.h in android project, and it does compile pass, but I couldn't get any output stream in console. Any suggestions ? Very thanks !

Multi-threaded support

Is there any effort to create a thread-safe version?

From a cursory glance, it looks like it would require some thread_local specifiers and locking the error stream.

EDIT: My cursory glance was too cursory. I thought I spotted some namespace scoped variables.

Add a flag to enable or disable dbg for release builds.

Not sure if there's currently a way to set a flag to enable or disable dbg depending on whether or not it's a debug build. If there is a flag, it should probably be documented, if not, maybe some kind of #define to effectively make the dbg macro do nothing.

Add a DBG_MACRO_NO_WARNING flag

We could add a DBG_MACRO_NO_WARNING compile-time flag to disable the generation of the #pragma message warning. This can be useful for our test-cases, for example. Or if someone really wants to use dbg in their codebase.

std::array not working with gcc-9.1 / c++17

The following piece of code fails to compile:

#include <vector>
#include <array>
#include <dbg.h>

int main() {
 std::array<unsigned int, 256> x{};
 dbg(x);
}

The problem boils down to

dbg.h: In substitution of ‘template<class T> using detect_size_t = decltype (dbg_macro::detail::{anonymous}::size(declval<T>())) [with T = std::array<unsigned int, 256>]’:
test.cc:12:39:   required from here
dbg.h:205:36: error: call of overloaded ‘size(std::array<unsigned int, 256>)’ is ambiguous
  205 | using detect_size_t = decltype(size(std::declval<T>()));
      |                                ~~~~^~~~~~~~~~~~~~~~~~~
dbg.h:189:16: note: candidate: ‘constexpr decltype (c.size()) dbg_macro::detail::{anonymous}::size(const T&) [with T = std::array<unsigned int, 256>; decltype (c.size()) = long unsigned int]’
  189 | constexpr auto size(const T& c) -> decltype(c.size()) {
      |                ^~~~
In file included from /usr/include/c++/9/string:54,
                 from /usr/include/c++/9/stdexcept:39,
                 from /usr/include/c++/9/array:39,
                 from test.cc:1:
/usr/include/c++/9/bits/range_access.h:242:5: note: candidate: ‘constexpr decltype (__cont.size()) std::size(const _Container&) [with _Container = std::array<unsigned int, 256>; decltype (__cont.size()) = long unsigned int]’
  242 |     size(const _Container& __cont) noexcept(noexcept(__cont.size()))
      |     ^~~~

Changing line 204 from:

template <typename T>
using detect_size_t = decltype(size(std::declval<T>()));

to

template <typename T>
using detect_size_t = decltype(std::declval<T>().size());

solves the problem for me

VS2015:error C2912

error C2912: explicit specialization;“bool dbg::pretty_print(std::ostream &,const dbg::time &)”is not a specialization of a function template.

When I try to comment the line of 'template <>', I get even more errors.

//template <>
inline bool pretty_print(std::ostream& stream, const time&);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.