Search code examples
c++templatestypeinfo

C++ template name pretty print


I have need to print indented template names for debugging purposes. For example, instead of single-line, I would like to indent name like this:

boost::phoenix::actor<
    boost::phoenix::composite<
      boost::phoenix::less_eval,
      boost::fusion::vector<
        boost::phoenix::argument<0>,
        boost::phoenix::argument<1>,

I started writing my own but is getting to be complicated. Is there an existing solution?

if there is not one, can you help me to finish up my implementation? I will post it if so.

Thanks

this is what typeid.name looks like,

boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::less_eval, 
boost::fusion::vector<boost::phoenix::argument<0>, 
boost::phoenix::composite<boost::phoenix::multiplies_eval, 
boost::fusion::vector<boost::phoenix::argument<1>, boost::phoenix::argument<2>,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, 
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, 
boost::fusion::void_, boost::fusion::void >, boost::fusion::void_, 
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, 
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, 
boost::fusion::void_> > >

this is my goal

 6 boost::phoenix::actor<
 7   boost::phoenix::composite<
 8     boost::phoenix::less_eval,
 9     boost::fusion::vector<
10       boost::phoenix::argument<0>,
11       boost::phoenix::composite<
12         boost::phoenix::multiplies_eval,
13         boost::fusion::vector<
14           boost::phoenix::argument<1>,
15           boost::phoenix::argument<2>,
16           boost::fusion::void_,
17           boost::fusion::void_,
18           boost::fusion::void_,
19           boost::fusion::void_,
20           boost::fusion::void_,
21           boost::fusion::void_,
22           boost::fusion::void_,
23           boost::fusion::void >, // indentation messed up
24           boost::fusion::void_,
25           boost::fusion::void_,
26           boost::fusion::void_,
27           boost::fusion::void_,
28           boost::fusion::void_,
29           boost::fusion::void_,
30           boost::fusion::void_,
31           boost::fusion::void_
32         >
33       >
34     >

so that I can actually read declaration


Solution

  • Certainly not the most elegant piece, but this should get you going regarding the closing tags:

    std::string indent(std::string str, const std::string &indent = "  ") {
        std::string indent_ = std::string("\n");
        size_t token = 0;
    
        while ((token = str.find_first_of("<>,", token)) != std::string::npos) {
            switch(str[token]) {
                case '<': indent_.append(indent);
                case ',': str.insert(token + 1, indent_);
                          break;
                case '>': indent_.erase(indent_.size() - indent.size());
                          str.insert(token, indent_);
            }
    
            token += indent_.size() + 1;            
            const size_t nw = str.find_first_not_of(" ", token);
            if(nw != std::string::npos) {
                str.erase(token, nw-token);
            }
        }
    
        return str;
    }