Как сделать макрос и / или шаблон variadi c и / или функцию, которая фиксирует выражение и его оценку? - PullRequest
0 голосов
/ 26 января 2020

Я перегружен класс различными << операторами

    inline QString operator<<(bool boolean) {
        return (boolean ? QString("true") : QString("false"));
    }
    inline QString operator<<(char const *string) {
        return QString(string);
    }
    inline QString operator<<(int number)                                       {
        return QString::number(number);
    }

В основном я хочу написать отладочный вывод, который фиксирует выражение, например:

#define DEBUG(...)
DEBUG(QString("foobar"), someObject.toInt());
// Expression 1: """QString("foobar")"""
// Expression 2: """someObject.toInt()"""

И объединяет его с оценкой:

#define DEBUG(...)
DEBUG(QString("foobar"), someObject.toInt());
// Evaluation 1: "foobar"
// Evaluation 2: "1234"

Предварительно все с

__FILE__;
QString::number(__LINE__);
__PRETTY_FUNCTION__;

И он должен вывести что-то вроде этого:

#define DEBUG(...)
DEBUG(QString("foobar"), someObject.toInt());
///////////////// Output /////////////////
File: /home/akiva/Programming/MyApp/source.cpp
Line: 123
Func: void doSomething();

QString("foobar")
"foobar"

someObject.toInt()
"1234"

У меня возникли проблемы с этим, поскольку рекурсивные макросы variadi c не совсем законны. У меня также есть некоторые дополнительные трудности, так как мой предыдущий метод использования шаблонов variadi c в сочетании с std::forward, насколько я могу судить, не работает в веб-сборке. В идеале решение после тестирования также будет совместимо с Wasm.

Спасибо.

1 Ответ

0 голосов
/ 26 января 2020

Я понял это, создав небольшой синтаксический анализатор для разбора исходного выражения. У парсера обязательно будут ошибки, так как я собрал их вместе за час.

Внутри класса:

static void _Continue(QStringList &sl)
{
    QString s;
    {
        s.append(sl.takeFirst()); // File
        s.append(":");
        s.append(sl.takeFirst()); // Line
        s.append("<br>  ");       // Outputting to a text box.
        s.append(sl.takeFirst()); // Func
    }

    /* Parse Expression */
    QStringList args;
    {
        QString expr(sl.takeFirst()); // Expression
        bool isQuote  (false); // ""
        bool isLiteral(false); // ''
        bool isPointer(false); // ->
        int roundLevel(0);   // ()
        int curlyLevel(0);   // {}
        int squarLevel(0);   // []
        int angleLevel(0);   // < > // Fixme handle <<, >>, <=  etc
        expr.remove(QRegularExpression("[/][*].*[*][/]")); // Remove Comments

        QString arg;
        QRegularExpression re_CommaWhitespaceAtBeginning("^[, \t\n]*");
        while (!expr.isEmpty()) {
            if (isPointer && expr.front().unicode() != u'>') { isPointer = false; }
            switch (expr.front().unicode()) {
            case u'-' : {
                isPointer = true; // potentially
                break;
            }
            case u'"' : {
                isQuote = !isQuote;
                break;
            }
            case u'\'': {
                isLiteral = !isLiteral;
                break;
            }
            case u'(' : {
                if (isQuote) { break; }
                roundLevel++;
                break;
            }
            case u')' : {
                if (isQuote) { break; }
                roundLevel--;
                break;
            }
            case u'[' : {
                if (isQuote) { break; }
                squarLevel++;
                break;
            }
            case u']' : {
                if (isQuote) { break; }
                squarLevel--;
                break;
            }
            case u'{' : {
                if (isQuote) { break; }
                curlyLevel++;
                break;
            }
            case u'}' : {
                if (isQuote) { break; }
                curlyLevel--;
                break;
            }
            case u'<' : {
                if (isQuote) { break; }
                angleLevel++;
                break;
            }
            case u'>' : {
                if (isQuote || isPointer) {
                    isPointer = false;
                    break;
                }
                angleLevel--;
                break;
            }
            case u'\\': {
                if (isQuote) { arg.append(expr.front()); }
                break;
            }
            case u',' : {
                if (isQuote
                    || isLiteral
                    || roundLevel
                    || curlyLevel
                    || squarLevel
                    || angleLevel) { break; }
                args << arg.remove(re_CommaWhitespaceAtBeginning);
                arg.clear();
                break;
            }
            default   : {

            }
            }
            arg.append(expr.front());
            expr.remove(0,1);
        }
        args << arg.remove(re_CommaWhitespaceAtBeginning);
    }

    // sl should now have only values;
    // args should be shorter than sl, even with error
    for (int i = 0; !args.isEmpty(); i++) {
        sl.replace(i, args.takeFirst() + "<br/>" + sl.at(i));
    }
    sl.prepend(s);

    /* Messages stored on a map, signal sent to update it. */
    MainWindow::s_StdoutMap.append(sl.join("<br/><br/>"));
    emit MainWindow::s_MW->on_actionUpdate_triggered();
}
template<typename type, typename ... T>
static void _Continue(QStringList &sl, type t, T ... args)
{
    sl << (*MainWindow::s_MW << t); // overloaded << operator to handle T
    MainWindow::_Continue(sl, args ...);
}
template<typename ... T>
static void _Start(QString file, int line, QString func, QString expr, T ... args)
{
    QStringList sl;
    {
        sl << file;
        sl << QString::number(line);
        sl << func;
        sl << expr;
    }
    MainWindow::_Continue(sl, args ...);
}
#define ct_Debug(...)MainWindow::_Start(__FILE__, __LINE__, __PRETTY_FUNCTION__,\
 #__VA_ARGS__, __VA_ARGS__)

И он дает мне вывод в соответствии с этим: enter image description here Если вам интересно, почему его нет в консоли Как сказано, это для веб-сборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...