{"id":10390,"date":"2021-03-29T11:06:56","date_gmt":"2021-03-29T09:06:56","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=10390"},"modified":"2023-01-17T12:25:17","modified_gmt":"2023-01-17T11:25:17","slug":"implementing-a-state-machine-in-c17-part-4-fun-with-types","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/implementing-a-state-machine-in-c17-part-4-fun-with-types\/","title":{"rendered":"Implementing a State Machine in C++17 \u2013 part 4 &#8211; fun with types"},"content":{"rendered":"\n<p>In the previous article, we\u2019ve played with creating and joining strings in compile time. Now with those tools at our disposal, we\u2019re ready to challenge the main goal \u2013 creating a transition table in compile time.\u00a0This article is a part of a bigger series (<a href=\"https:\/\/sii.pl\/blog\/implementing-a-state-machine-in-c17\/\" class=\"ek-link\">part1<\/a>, part2,\u00a0<a href=\"https:\/\/sii.pl\/blog\/implementing-a-state-machine-in-c17-part-3-compile-time-strings\/\" class=\"ek-link\">part3<\/a>) and since it references previous solutions and ideas a lot I highly recommend reading all previous articles before reading this one. Also, this part is a bit lengthy so I recommend grabbing a cup of coffee or tea beforehand\u00a0\ud83d\ude42<\/p>\n\n\n\n<p>So, what is a transition table anyway?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Definition<\/strong><\/h2>\n\n\n\n<p>Let\u2019s start with defining a transition function. In essence, it\u2019s a function that when given the current state and an event returns the next state the state machine should transition to. Something like this:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/transition.png\"><img decoding=\"async\" width=\"246\" height=\"122\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/transition.png\" alt=\"\" class=\"wp-image-18361\"\/><\/a><\/figure><\/div>\n\n\n\n<p>Notice that states used in this series return an action instead of the next state, which leads us to a slightly modified definition:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/2.png\"><img decoding=\"async\" width=\"259\" height=\"175\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/01\/2.png\" alt=\"\" class=\"wp-image-18363\"\/><\/a><\/figure><\/div>\n\n\n\n<div style=\"height:10px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Problem statement<\/strong><\/h2>\n\n\n\n<p>All possible states and events are known at compile-time and are available directly in the code so using them is trivial. Getting the resulting action is a bit tricky though since it\u2019s encoded in the type signature of the handle method. To make things even more complicated, sometimes the handle method could be defined somewhere else or overloaded several times in the inheritance chain. The bottom line is that in the end, the compiler needs to know unambiguously which handle method we want to call and that mechanism is exactly what we\u2019re going to use to solve this problem\u00a0\ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Using types as values<\/strong><\/h2>\n\n\n\n<p>Most of the time, we think of a type as just a label that\u2019s attached to an underlying value. The truth is that we can transform types and use them as values. We just need a container to store the results of our computations. Let\u2019s start with something like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename... Ts&gt;\nstruct Types {\n};\n<\/pre><\/div>\n\n\n<p>We\u2019ll use this structure to bind several types together and manipulate them as a set. Even though it\u2019s not a perfect representation of a set (<code>Types&lt;A, B> != Types&lt;B, A> != Types&lt;B, A, A><\/code>) it\u2019s more than enough for our use\u00a0\ud83d\ude42 The first operation we\u2019d need is combining several types into one, which could be implemented like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename... Lhs, typename... Rhs&gt;\nconstexpr auto operator+(Types&lt;Lhs...&gt;, Types&lt;Rhs...&gt;)\n{\n    return Types&lt;Lhs..., Rhs...&gt;{};\n}\n<\/pre><\/div>\n\n\n<p>Now it\u2019s time to get creative\u00a0\ud83d\ude42<\/p>\n\n\n\n<p>\u00a0As you remember, a transition function accepts a pair of a state and an event. In other words, the domain of such function is the cartesian product of two sets \u2013 states and events. What we\u2019re trying to achieve here is something along these lines:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nTypes&lt;White, Black&gt; * Types&lt;Cat, Dog&gt; = Types&lt;Types&lt;White, Cat&gt;, Types&lt;White, Dog&gt;, Types&lt;Black, Cat&gt;, Types&lt;Black, Dog&gt;&gt;\n<\/pre><\/div>\n\n\n<p>The reason we need to nest the&nbsp;<code>Type<\/code>structure is that we don\u2019t want to lose information on how individual types are grouped while still being able to return a single \u2018type\u2019 that corresponds to the result of the cartesian product.<\/p>\n\n\n\n<p>Let\u2019s start with something simpler:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nTypes&lt;A&gt; * Types&lt;B1, ..., Bn&gt; = Types&lt;Types&lt;A, B&gt;, ..., Types&lt;A, Bn&gt;&gt;\n<\/pre><\/div>\n\n\n<p>It\u2019s pretty straightforward. If we have only 1 type on the left we just need to append that type to all types on the right:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename Lhs, typename... Rhs&gt;\nconstexpr auto operator*(Types&lt;Lhs&gt;, Types&lt;Rhs...&gt;)\n{\n    return Types&lt;Types&lt;Lhs, Rhs&gt;...&gt;{};\n}\n<\/pre><\/div>\n\n\n<p>So now what if we have multiple types on the left? We just need to extract each one on the left side, process it as it was a single type, and combine the results<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nTypes&lt;A1, ..., Am&gt; * Types&lt;B1, ..., Bn&gt; = Types&lt;A1&gt; * Types&lt;B1, ..., Bn&gt; + ... + Types&lt;Am&gt; * Types&lt;B1, ..., Bn&gt;\n<\/pre><\/div>\n\n\n<p>This is quite easy to implement by using fold expressions from C++17:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename... Lhs, typename Rhs&gt;\nconstexpr auto operator*(Types&lt;Lhs...&gt;, Rhs rhs)\n{\n    return ((Types&lt;Lhs&gt;{} * rhs) + ...);\n}\n<\/pre><\/div>\n\n\n<p>Let\u2019s say we have a StateMachine. How do we extract all state types used? Since each StateMachine is parametrized exactly by that information, extracting it is trivial:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename... States&gt;\nclass StateMachine\n{\npublic:\n\/*...*\/\n    constexpr static Types&lt;States...&gt; getStateTypes() { return {}; }\n\/*...*\/\n};\n<\/pre><\/div>\n\n\n<p>Now. How to check if all of this works? Usually, when writing some template and type intensive code I use a simple debug utility that helps me print the underlying types. It can be implemented like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename T&gt;\nvoid debug(T&amp;&amp;)\n{\n    std::cerr &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; std::endl;\n}\n<\/pre><\/div>\n\n\n<p>Unfortunately\u00a0<code>__PRETTY_FUNCTION__<\/code>\u00a0is not part of the standard, but both gcc and clang implement so it\u2019s likely that it\u2019s already available in your toolchain\u00a0\ud83d\ude42<\/p>\n\n\n\n<p>Great! Let\u2019s run it on the door example we used in previous articles and see how it works:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nTypes stateTypes = Door::getStateTypes();\nTypes&lt;OpenEvent, CloseEvent, LockEvent, UnlockEvent&gt; eventTypes;\ndebug(stateTypes * eventTypes);\n<\/pre><\/div>\n\n\n<p>We should see an output similar to this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nvoid debug(T &amp;&amp;) &#x5B;T = Types&lt;Types&lt;ClosedState, OpenEvent&gt;, Types&lt;ClosedState, CloseEvent&gt;, Types&lt;ClosedState, \nLockEvent&gt;, Types&lt;ClosedState, UnlockEvent&gt;, Types&lt;OpenState, OpenEvent&gt;, Types&lt;OpenState, CloseEvent&gt;, Types&lt;OpenState, LockEvent&gt;, Types&lt;OpenState, UnlockEvent&gt;, Types&lt;LockedState, OpenEvent&gt;, Types&lt;LockedState, CloseEvent&gt;, Types&lt;LockedState, LockEvent&gt;, Types&lt;LockedState, UnlockEvent&gt; &gt;]\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Making it functional<\/strong><\/h2>\n\n\n\n<p>The biggest gain of having a dedicated object representing a set of possible types is the possibility to perform different transformations on it. Let\u2019s use the \u2018pipe\u2019 operator to execute an operation on all stored types.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename... Ts, typename Operation&gt;\nconstexpr auto operator|(Types&lt;Ts...&gt;, Operation oper)\n{\n    return oper(Types&lt;Ts&gt;{}...);\n}\n<\/pre><\/div>\n\n\n<p>Even though this implementation is quite flexible (since we can return any type) it\u2019s not very convenient. In most cases, we want to execute something on each held type and then combine the results. A simple wrapper can help us with that:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename Operation&gt;\nclass MapAndJoin\n{\npublic:\n    constexpr MapAndJoin(Operation operation)\n        : operation(std::move(operation))\n    {\n    }\n\n    template &lt;typename... Ts&gt;\n    constexpr auto operator()(Types&lt;Ts&gt;... rhs)\n    {\n        return (operation(rhs) + ...);\n    }\n\nprivate:\n    Operation operation;\n};\n<\/pre><\/div>\n\n\n<p>The overall idea is quite simple. We use fold expressions to call\u00a0<code>operation<\/code>\u00a0on each type and then we join the results by adding them together. The next step is to transform our set of state-event pairs into a set of underlying actions.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nstruct ResolveAction\n{\n    template &lt;typename State, typename Event&gt;\n    constexpr auto operator()(Types&lt;State, Event&gt;)\n    {\n        using Action = decltype(std::declval&lt;State&gt;().handle(std::declval&lt;Event&gt;()));\n        return Types&lt;Action&gt;{};\n    }\n\n    template &lt;typename State, typename Event&gt;\n    constexpr auto operator()(Types&lt;Types&lt;State, Event&gt;&gt;)\n    {\n        return (*this)(Types&lt;State, Event&gt;{});\n    }\n};\n<\/pre><\/div>\n\n\n<p><code>std::declval<\/code>\u00a0allows us to \u2018pretend\u2019 that we have an object of a given type, which is handy, especially when dealing with overloaded functions such as\u00a0<code>handle<\/code>. And why there\u2019s a double nested Types overload you might ask? It comes down to how\u00a0<code>MapAndJoin<\/code>\u00a0works.\u00a0<code>Types&lt;A, B, C><\/code>\u00a0will be converted to\u00a0<code>oper(Types&lt;A>{}) + oper(Types&lt;B>{}) + oper(Types&lt;C>{})<\/code>. Let\u2019s run it on our example and see how it works<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nvoid debug(T &amp;&amp;) &#x5B;T = Types&lt;TransitionTo&lt;OpenState&gt;, Nothing, TransitionTo&lt;LockedState&gt;, Nothing, Nothing, TransitionTo&lt;ClosedState&gt;, Nothing, Nothing, Nothing, Nothing, Nothing, Maybe&lt;TransitionTo&lt;ClosedState&gt;&gt;&gt;]\n<\/pre><\/div>\n\n\n<p>Awesome! \ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Generating strings<\/strong><\/h2>\n\n\n\n<p>Most of the work done so far was related to manipulating types. It\u2019s time to convert those types into compile-time strings that we can print later on. Let\u2019s assume that for user-defined states and events exists a \u2018stringification\u2019 function. To eliminate a bit of boilerplate, we can write a preprocessor macro to generate all the needed implementations:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n#define STRINGIFY_IMPL(TYPE) &#x5B;&#x5B;maybe_unused]] static constexpr auto stringify(Types&lt;TYPE&gt;) { return StaticString{#TYPE}; }\n\nSTRINGIFY_IMPL(OpenEvent)\nSTRINGIFY_IMPL(CloseEvent)\nSTRINGIFY_IMPL(LockEvent)\nSTRINGIFY_IMPL(UnlockEvent)\n\nSTRINGIFY_IMPL(ClosedState)\nSTRINGIFY_IMPL(OpenState)\nSTRINGIFY_IMPL(LockedState)\n<\/pre><\/div>\n\n\n<p>Now, what about stringifying actions? It\u2019s a bit more difficult since actions can be parametrized by other actions\/states\/events. Thankfully, since we can combine strings in compile time we can generate the string for a subexpression and join it with a known prefix or suffix. Let\u2019s implement it for actions used in our example<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;typename State&gt;\nstatic constexpr auto stringify(Types&lt;TransitionTo&lt;State&gt;&gt;) { return StaticString{&quot;TransitionTo&lt;&quot;} + stringify(Types&lt;State&gt;{}) + StaticString{&quot;&gt;&quot;}; }\n\ntemplate &lt;typename Action&gt;\nstatic constexpr auto stringify(Types&lt;Maybe&lt;Action&gt;&gt;) { return StaticString{&quot;Maybe&lt;&quot;} + stringify(Types&lt;Action&gt;{}) + StaticString{&quot;&gt;&quot;}; }\n\nstatic constexpr auto stringify(Types&lt;Nothing&gt;) { return StaticString{&quot;Nothing&quot;}; }\n<\/pre><\/div>\n\n\n<p>Assuming we know how to stringify each state, event, and action used in our example we can proceed to generate the transition table. The table itself will be quite simple. In the first row, we\u2019ll list all the events and in the first column, we\u2019ll list all the states. The rest will be actions executed when we handle a given event in a particular state. Since both the first row and first column are displayed a bit differently, let\u2019s add a dummy marker type \u2013\u00a0<code>Header<\/code>\u00a0to handle such cases. Additionally, in the future, we might want to change the format of the strings so let\u2019s create a separate\u00a0<code>Stringifier<\/code>\u00a0class that\u2019d responsible for generating all the strings:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nstruct Header {};\n\nstruct SimpleStringifier\n{\n    constexpr auto operator()(Types&lt;Header&gt;) const\n    {\n        return StaticString{&quot;&quot;};\n    }\n\n    template &lt;typename T&gt;\n    constexpr auto operator()(Types&lt;T&gt; type) const\n    {\n        return stringify(type);\n    }\n};\n\ntemplate &lt;typename Stringifier, typename State&gt;\nclass GenerateRow\n{\npublic:\n    constexpr GenerateRow(Stringifier str, Types&lt;State&gt;)\n        : str(str)\n    {\n    }\n\n    constexpr auto operator()(Types&lt;State&gt; state) const\n    {\n        return str(state);\n    }\n\n    template &lt;typename Event&gt;\n    constexpr auto operator()(Types&lt;Event&gt;) const\n    {\n        auto action = ResolveAction{}(Types&lt;Types&lt;State, Event&gt;&gt;{});\n        return StaticString{&quot; | &quot;} + str(action);\n    }\n\nprivate:\n    const Stringifier str;\n};\n\ntemplate &lt;typename Stringifier&gt;\nclass GenerateRow&lt;Stringifier, Header&gt;\n{\npublic:\n    constexpr GenerateRow(Stringifier str, Types&lt;Header&gt;)\n        : str(str)\n    {\n    }\n\n    constexpr auto operator()(Types&lt;Header&gt; header) const\n    {\n        return str(header);\n    }\n\n    template &lt;typename Event&gt;\n    constexpr auto operator()(Types&lt;Event&gt; event) const\n    {\n        return StaticString{&quot; | &quot;} + str(event);\n    }\n\nprivate:\n    const Stringifier str;\n};\n\ntemplate &lt;typename Stringifier, typename... Events&gt;\nclass GenerateTable\n{\npublic:\n    constexpr GenerateTable(Stringifier str, Types&lt;Events...&gt;)\n        : str(str)\n    {\n    }\n\n    template &lt;typename State&gt;\n    constexpr auto operator()(Types&lt;State&gt; state) const\n    {\n        return (Types&lt;State, Events...&gt;{} | MapAndJoin{GenerateRow{str, state}}) + StaticString{&quot;\\n&quot;};\n    }\n\nprivate:\n    const Stringifier str;\n};\n\ntemplate &lt;typename... StateTypes, typename... EventTypes&gt;\nconstexpr auto generateTransitionTable(Types&lt;StateTypes...&gt; states, Types&lt;EventTypes...&gt; events)\n{\n    constexpr SimpleStringifier stringifier;\n    constexpr auto result = (Types&lt;Header&gt;{} + states) | MapAndJoin{GenerateTable{stringifier, events}};\n    return result;\n}\n\nint main()\n{\n    std::cout &lt;&lt; generateTransitionTable(Door::getStateTypes(), Types&lt;OpenEvent, CloseEvent, LockEvent, UnlockEvent&gt;{}).data() &lt;&lt; std::endl;\n    return 0;\n}\n<\/pre><\/div>\n\n\n<p>The trick here is that we have a partial specialization for GenerateRow. This allows us to switch implementation for header rows and use the default for others. Let\u2019s give it a go:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n | OpenEvent | CloseEvent | LockEvent | UnlockEvent\nClosedState , TransitionTo&lt;OpenState&gt; , Nothing , TransitionTo&lt;LockedState&gt; , Nothing\nOpenState , Nothing , TransitionTo&lt;ClosedState&gt; , Nothing , Nothing\nLockedState , Nothing , Nothing , Nothing , Maybe&lt;TransitionTo&lt;ClosedState&gt;&gt;\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Making it pretty<\/strong><\/h2>\n\n\n\n<p>As you can see the table is pretty wobbly due to different cell widths. There are a couple of ways to fix it. For now, let\u2019s calculate the maximum width of all cells, and let\u2019s fill smaller cells with spaces accordingly. Let\u2019s start by adding the ability to resize to our compile-time strings. We already have a\u00a0<code>resize<\/code>\u00a0function for std::array. The problem is that when it is expanding the array it leaves excess elements default-initialized, whereas we want them to be initialized to spaces. Let\u2019s modify our implementation to allow providing a default filler value<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;std::size_t NewSize, typename T, std::size_t OldSize, std::size_t... Indexes&gt;\nconstexpr std::array&lt;T, NewSize&gt; resize(const std::array&lt;T, OldSize&gt;&amp; arr, std::remove_const_t&lt;T&gt; defaultValue, std::index_sequence&lt;Indexes...&gt;)\n{\n    return {((Indexes &lt; OldSize) ? arr&#x5B;Indexes] : defaultValue)...};\n}\n\ntemplate &lt;std::size_t NewSize, typename T, std::size_t OldSize&gt;\nconstexpr std::array&lt;T, NewSize&gt; resize(const std::array&lt;T, OldSize&gt;&amp; arr, std::remove_const_t&lt;T&gt; defaultValue)\n{\n    return resize&lt;NewSize&gt;(arr, defaultValue, std::make_index_sequence&lt;NewSize&gt;());\n}\n<\/pre><\/div>\n\n\n<p>That\u00a0<code>std::remove_const_t&lt;T><\/code>\u00a0might need a bit of explaining. Our compile strings use\u00a0<code>const char<\/code>\u00a0as the underlying type, but passing a char literal would deduce\u00a0<code>char<\/code>. Since\u00a0<code>T<\/code>\u00a0cannot be both deduced as\u00a0<code>const char<\/code>\u00a0and\u00a0<code>char<\/code>\u00a0compiler raises a compilation error. Wrapping\u00a0<code>T<\/code>\u00a0in a std::remove_const_t has a side effect that it stops deducing T from it. What\u2019s left is a\u00a0<code>changeSize<\/code>\u00a0implementation for\u00a0<code>StaticString<\/code><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;std::size_t TargetLen&gt;\nconstexpr StaticString&lt;TargetLen + 1&gt; changeLength(char fill) const\n{\n    constexpr std::array&lt;const char, 1&gt; stringEnd{&#039;\\0&#039;};\n    return join(resize&lt;TargetLen&gt;(resize&lt;N-1&gt;(chars, fill), fill), stringEnd);\n}\n<\/pre><\/div>\n\n\n<p>First, we trim the trailing&nbsp;<code>\\0<\/code>&nbsp;character, then we resize it and we append \u2018\\0\u2019 at the end.<\/p>\n\n\n\n<p>So how to calculate the maximum length of all strings used in the table? Let\u2019s start by adding a small utility function to\u00a0<code>StaticString<\/code>\u00a0class:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nconstexpr std::size_t length() const\n{\n    return N - 1;\n}\n<\/pre><\/div>\n\n\n<p>It\u2019s pretty straightforward and it will be quite useful in a moment\u00a0\ud83d\ude42<\/p>\n\n\n\n<p>Provided we have a bunch of states and actions wrapped in\u00a0<code>Types<\/code>, we can calculate the max size as follows:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;std::size_t X&gt;\nstruct Maximum\n{\n    template &lt;std::size_t Y&gt;\n    constexpr auto operator+(Maximum&lt;Y&gt;)\n    {\n        return Maximum&lt;std::max(X, Y)&gt;{};\n    }\n\n    static constexpr auto value()\n    {\n        return X;\n    }\n};\n\nstruct CalculateMaxLength\n{\n    template &lt;typename T&gt;\n    constexpr auto operator()(Types&lt;T&gt; type)\n    {\n        return Maximum&lt;stringify(type).length()&gt;{};\n    }\n};\n\n\/*\n...\n*\/\n    constexpr auto actions = (states * events) | MapAndJoin(ResolveAction{});\n    constexpr auto maxWidth = (states + events + actions) | MapAndJoin(CalculateMaxLength{});\n\/*\n...\n*\/\n<\/pre><\/div>\n\n\n<p>We start by calculating all the resulting actions. Then we calculate the maximum length for all states, events, and actions combined. Do you remember how\u00a0<code>MapAndJoin<\/code>\u00a0was defined? For each type, it executes the provided operation and \u2018glues\u2019 the results together by calling \u2018+\u2019 on them. This way we can define a special\u00a0<code>Maximum<\/code>\u00a0type that takes the maximum of two numbers when \u2018added\u2019. The only thing left is to create a new \u2018stringifier\u2019 that will expand all the strings if necessary:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\ntemplate &lt;std::size_t Width&gt;\nstruct ConstantWidthStringifier\n{\n    constexpr auto operator()(Types&lt;Header&gt;) const\n    {\n        return StaticString{&quot;&quot;}.template changeLength&lt;Width&gt;(&#039; &#039;);\n    }\n\n    template &lt;typename T&gt;\n    constexpr auto operator()(Types&lt;T&gt; type) const\n    {\n        return stringify(type).template changeLength&lt;Width&gt;(&#039; &#039;);\n    }\n};\n\ntemplate &lt;typename... StateTypes, typename... EventTypes&gt;\nconstexpr auto generatePrettyTransitionTable(Types&lt;StateTypes...&gt; states, Types&lt;EventTypes...&gt; events)\n{\n    constexpr auto actions = (states * events) | MapAndJoin(ResolveAction{});\n    constexpr auto maxWidth = (states + events + actions) | MapAndJoin(CalculateMaxLength{});\n    constexpr ConstantWidthStringifier&lt;maxWidth.value()&gt; stringifier{};\n    constexpr auto result = (Types&lt;Header&gt;{} + states) | MapAndJoin{GenerateTable{stringifier, events}};\n    return result;\n}\n<\/pre><\/div>\n\n\n<p>The output of this function looks like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\n              | OpenEvent                 | CloseEvent                 | LockEvent                  | UnlockEvent\nClosedState   | TransitionTo&lt;OpenState&gt;   | Nothing                    | TransitionTo&lt;LockedState&gt;  | Nothing\nOpenState     | Nothing                   | TransitionTo&lt;ClosedState&gt;  | Nothing                    | Nothing\nLockedState   | Nothing                   | Nothing                    | Nothing                    | Maybe&lt;TransitionTo&lt;ClosedState&gt;&gt;\n<\/pre><\/div>\n\n\n<p>Success!\u00a0\ud83d\ude42 The whole transition table for our toy state machine was reduced to a single compile-time string. I hope it shows how much can be achieved in compile-time by leveraging type information\u00a0\ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Final word<\/strong><\/h2>\n\n\n\n<p>This article ends a rather long series of articles related to a possible implementation of a State Machine by using features from C++17. We\u2019ve covered different topics, from the state machine itself, through different compile-time debug utilities and a hint of functional type-based calculations :). I hope you had as much fun reading it as I had writing it :). As always, all the code and the examples used are available in my&nbsp;<a href=\"https:\/\/github.com\/AdamsPL\/state-machine\/\" rel=\"nofollow\" >GitHub repository<\/a>.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;10390&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;3&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 3)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Implementing a State Machine in C++17 \u2013 part 4 - fun with types&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 3)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>In the previous article, we\u2019ve played with creating and joining strings in compile time. Now with those tools at our &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/en\/implementing-a-state-machine-in-c17-part-4-fun-with-types\/\">Continued<\/a><\/p>\n","protected":false},"author":193,"featured_media":10403,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":8,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1320],"tags":[1342,1395,1375],"class_list":["post-10390","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hard-development","tag-embedded-en","tag-c17-en","tag-embedded-competency-center-en"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2021\/03\/TESTING-API.jpg","category_names":["Hard development"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/10390"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/193"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=10390"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/10390\/revisions"}],"predecessor-version":[{"id":18390,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/10390\/revisions\/18390"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/10403"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=10390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=10390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=10390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}