c++qtcharswitch-statementqchar

How can I evaluate a QChar object in a switch?


Going through a bunch of code, looking to improve it.

I came across this bit:

if (c == '<' || c == '>') {
    pattern.append("\\b");
} else if (c == 'a') {
    pattern.append("[a-zA-Z]");
} else if (c == 'A') {
    pattern.append("[^a-zA-Z]");
} else if (c == 'h') {
    pattern.append("[A-Za-z_]");
} else if (c == 'H') {
    pattern.append("[^A-Za-z_]");
} else if (c == 'c' || c == 'C') {
    ignorecase = (c == 'c');
} else if (c == 'l') {
    pattern.append("[a-z]");
} else if (c == 'L') {
    pattern.append("[^a-z]");
} else if (c == 'o') {
    pattern.append("[0-7]");
} else if (c == 'O') {
    pattern.append("[^0-7]");
} else if (c == 'u') {
    pattern.append("[A-Z]");
} else if (c == 'U') {
    pattern.append("[^A-Z]");
} else if (c == 'x') {
    pattern.append("[0-9A-Fa-f]");
} else if (c == 'X') {
    pattern.append("[^0-9A-Fa-f]");
} else if (c == '=') {
    pattern.append("?");
} else {
    pattern.append('\\');
    pattern.append(c);
}

If c was a char, this would be easy to turn into a switch. c is a QChar; How should I turn QChar into an interger and reliably compare it to the various cases >, = etc?


Solution

  • A QChar is a wrapper for a 16-bit UTF-16 character.

    You can retrieve the value using QChar::unicode() that returns an unsigned short.

    You can the write your switch like this:

    QChar c;
    switch (c.unicode()) {
        case u'a':
        ...
    }
    

    Be careful with your case statements as if you use 8-bit char literals, it might not work as expected.

    For instance é might be 0xE9 (Latin-1, UTF16), or 0x82 (CP437) or even 0xC3 0xA9 (UTF-8, which will not compile as it needs 2 characters).

    The solution is to use UTF-16 literals that are part of C++ since C++11. For exampleu'é' will always be compiled as a char16_t (~unsigned short) of value 0x00E9.