Question

J'ai besoin d'imprimer les noms de modèle dentelées pour des fins de débogage. Par exemple, au lieu d'une seule ligne, je voudrais le nom tiret comme ceci:

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

J'ai commencé à écrire mon propre mais commence à être compliqué. Y at-il une solution existante?

s'il n'y en a pas, pouvez-vous me aider à finir ma mise en œuvre? Je vais poster le cas échéant.

Merci

est ce que typeid.name ressemble,

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_> > >

est mon objectif

 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     >

pour que je puisse réellement lire la déclaration

Était-ce utile?

La solution

Certainement pas la pièce la plus élégante, mais vous devriez y aller sur les balises de fermeture:

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;
}

Autres conseils

Ajustement mineur du programme gf, surtout ne pas diviser courts modèles

#ifndef PRETTY_NAME_HPP
#define PRETTY_NAME_HPP

#include <typeinfo>
#include <string>
#include <iostream>
#include <cxxabi.h>

#define TYPENAME(TYPE) typeid_name(typeid(TYPE).name())

std::string indent(std::string str, const std::string &indent = "  ") {
    std::string indent_ = std::string("\n");
    size_t token = 0;

    bool one_line = false;
    while ((token = str.find_first_of("<>,", token)) != std::string::npos) {
        size_t size = str.size();
        size_t close, open, comma;

        switch(str[token]) {
        case '<':
            close = str.find(">", token+1);
            open = str.find("<", token+1);
            comma = str.find(",", token+1);
            one_line = !(close > open) && !(comma < close);

            if (one_line) break;
            indent_.append(indent);

        case ',':
            str.insert(token + 1, indent_);
            break;

        case '>':
            if (!one_line) {
                indent_.erase(indent_.size() - indent.size());
                str.insert(token, indent_);
            }
            one_line = false;
        }

        token += 1 + str.size() - size;

        const size_t nw = str.find_first_not_of(" ", token);
        if(nw != std::string::npos) {
            str.erase(token, nw-token);
        }
    }

    return str;
}
std::string typeid_name(const char* name) {
// #ifdef HAVE_CXA_DEMANGLE
    size_t size;
    int status;
    char *buf = abi::__cxa_demangle(name, NULL, &size, &status);
    if (status  != 0) throw status;
    std::string string(buf);
    free(buf);
    return indent(string);
// #else
//     return name;
// #endif
}

#endif /* PRETTY_NAME_HPP */

Que diriez-vous, copier dans le presse-papiers, puis

$ xclip -o | clang-format

Par exemple, cela prend modèle de l'OP

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_> > >

Pas idéal, parce qu'il ya une part d'erreur en elle. Mais il est assez facile de trouver l'erreur (le > supplémentaire après la void au milieu doit être déplacé à la fin). Si nous fixons, nous obtenons

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_>>>>>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top