Home Simple "switch" for strings 🎲
Post
Cancel

Simple "switch" for strings 🎲

C++ can’t have strings (or string literals) in switch-expressions as case values.

There can only be constant integral values or enum values (an enum itself is an integer type secretly).

Such a strict restriction is made for practical reasons - switch expressions in executable code can be transformed into a super-optimized form using branch table, when the integer value of the argument simply calculates the address of the code to jump to.

It is clear that it is impossible to make branch tables for strings, so the efficiency of such a switch will not differ from a bunch of if-expressions.

In other programming languages, strings in switch are possible: Java 7, C# 6, but these languages do not focus on maximum performance.

But you can make a self-written simple “switch” to simplify this code:

1
2
3
4
5
6
7
8
9
10
11
12
    Color color = UnknownColor;
    if (argv[i] == "red") {
        color = Red;
    } else if (argv[i] == "orange") {
        color = Orange;
    } else if (argv[i] == "yellow") {
        color = Yellow;
    } else if (argv[i] == "green") {
        color = Green;
    } else if (argv[i] == "violet" || argv[i] == "purple") {
        color = Violet;
    }

into this:

1
2
3
4
5
6
7
    Color color = StringSwitch<Color>(argv[i])
        .Case("red", Red)
        .Case("orange", Orange)
        .Case("yellow", Yellow)
        .Case("green", Green)
        .Cases("violet", "purple", Violet)
        .Default(UnknownColor);

There is a StringSwitch realization in llvm: StringSwitch.h.

This class has just two fields:

  1. std::string_view str - the string (argv[i] in our case)
  2. std::optional<T> value - the resulting value (in our case T == Color)

When calling the Case method, if value is not set yet and the given string equals to str, then value is set.

There are EndsWith and StartsWith methods which will fill value if a part of str equals to the given string.

There are corresponding case-insensitive methods, as well as Case methods for multiple values.

Finally there is a conversion operator (in our case it converts to Color).

In my opinion, one can also make a LambdaSwitch class, which, unlike StringSwitch, should accept lambdas, and set a value if the given lambda returns true. 🙂

This post is licensed under CC BY 4.0 by the author.

clang-format: an architectural failure? 🩼

📚 Book review: "Team Geek" (2014)