sml2: A Powerful C++20 State Machine Library

sml2: A Powerful C++20 State Machine Library

In modern software development, state machines are a crucial design pattern that helps developers better manage and organize complex program logic. sml2 is a state machine library based on C++20 that offers powerful features and efficient performance while maintaining simplicity and ease of use.

Features

Based on UML-2.5

sml2 adheres to the UML-2.5 state machine language specification, which means it can support complex event handling and state transition logic. Developers can use it to build systems with clear states and event-driven behaviors, thereby improving code readability and maintainability.

Compile-time Self-testing

One notable feature of sml2 is its ability to perform self-testing at compile time. When the library is included or imported, all tests are executed during the compilation phase. This provides developers with an additional guarantee that the library’s functionality meets expectations at compile time, thus reducing potential issues at runtime.

Zero Dependencies

sml2 is a single-header library with no external dependencies. This means developers can easily integrate it into any project without worrying about compatibility issues with other libraries. Additionally, it does not require C++ exception handling or runtime type information (RTTI), making it particularly suitable for embedded systems with strict performance and resource requirements.

High Performance

sml2 focuses on optimizing runtime performance. It achieves zero-overhead state machines through template metaprogramming techniques, meaning that the execution efficiency of the state machine is very high at runtime without introducing additional performance overhead. This is a significant advantage for applications that need to handle a large number of events or are performance-sensitive.

Fast Compilation

In addition to runtime performance, sml2 also emphasizes compilation speed. By utilizing C++20 features and template metaprogramming techniques, it ensures fast compilation times. This is crucial for large projects, as quick compilation times can significantly enhance development efficiency.

Usage Example

sml2: A Powerful C++20 State Machine Library

Here is a simple usage example demonstrating how to build a state machine using sml2:

// Define events
struct connect {};
struct ping {
    bool valid = false;
};
struct established {};
struct timeout {};
struct disconnect {};

int main() {
    // Define state machine
    sml::sm connection = [] {
        // Define guards
        auto is_valid  = [](const auto& event) { return event.valid; };

        // Define actions
        auto establish = [] { std::puts("establish"); };
        auto close     = [] { std::puts("close"); };
        auto setup     = [] { std::puts("setup"); };

        using namespace sml::dsl;
        // Define transition table
        return transition_table{
            *"Disconnected"_s + event<connect> / establish    = "Connecting"_s,
             "Connecting"_s   + event<established>            = "Connected"_s,
             "Connected"_s    + event<ping>[is_valid] / setup,
             "Connected"_s    + event<timeout> / establish    = "Connecting"_s,
             "Connected"_s    + event<disconnect> / close     = "Disconnected"_s,
        };
    };

    // Process events
    connection.process_event(connect{});
    connection.process_event(established{});
    connection.process_event(ping{.valid = true});
    connection.process_event(disconnect{});
}

In this example, we define several event types, such as connect, ping, etc., and then create a state machine connection. The state machine’s transition table defines the event handling logic for different states. For instance, when in the "Disconnected" state, receiving a connect event triggers the establish action and transitions to the "Connecting" state.

Applicable Scenarios

sml2 has a wide range of application scenarios. It is suitable for any system that requires clear state management and event-driven logic, whether it be desktop applications, server-side software, or embedded systems. Due to its high performance and zero-dependency characteristics, sml2 is particularly well-suited for embedded development with strict performance and resource requirements.

Conclusion

sml2 is a powerful and efficient C++20 state machine library. It is based on the UML-2.5 specification and supports complex event handling and state transition logic. Through compile-time self-testing, sml2 provides an additional reliability guarantee. Its zero-dependency, high performance, and fast compilation features make it an ideal choice for developers. Whether you are developing large complex systems or performance-sensitive embedded applications, sml2 can help you build clear, efficient, and maintainable code.

Leave a Comment