Hi HN!
I've built [CXXStateTree](https://github.com/ZigRazor/CXXStateTree), a modern C++ header-only library to create hierarchical state machines with clean, intuitive APIs.
It supports: - Deeply nested states - Entry/exit handlers - State transitions with guards and actions - Asynchronous transitions with `co_await` (C++20 coroutines) - Optional runtime type identification for flexibility
It's ideal for complex control logic, embedded systems, games, robotics, and anywhere you'd use a finite state machine.
I’d love feedback, use cases, or contributions from the community!
The Readme sais "zero heap allocations" but the code uses list and unordered map and moves, did you mean "zero allocations after state tree building"?
Also for embedded it would be useful to separate all in/out, dot export etc. to a second library that you can omit on small targets.
There may be no heap at all and memory must be pre-allocated at system initialization. Otherwise CXXStateTree sounds like it could be very useful in my Embedded devices, which rarely have enough Flash or RAM space, which is the nature of the work.
https://misra.org.uk
there are about 1 million c++ state machines, and sml happens to be the best, or one of them. how does yours differentiate?
What exactly happened there? It looks like make_transition_table() is doing some serious magic. Or are the state transitions evaluated at compile-time given that there is no input in the example, and then the transition table gets compiled out?
Anyway, I think it would help OP's library to have some assembly output in the readme as well.
[0]: https://en.cppreference.com/w/cpp/language/user_literal.html
[1]: https://github.com/boost-ext/sml/blob/f232328b49adf708737bef...
#pragma once is broken by design
No, this is completely wrong. Pragma once is non-standard compiler directive. It might be supported by some compilers such as msvc but technically it is not even C++.
There are only two options: include guards, and modules.
In the C++ community (as lots of other things are), rejecting `#pragma once` is a long-standing tradition of worshipping the decaying body of prehistoric compilers for
It's unclear what benefits this approach has achieved, but don't disturb it, or else.
`#pragma once` seems to be far preferred for internal code, there's an argument for being strictly conforming if you're putting out a library. I've converted stuff to `#ifndef` before sharing it, but I think heavy C++ people usually type `#pragma once` in the privacy of their own little repository.
- `spdlog`: `#pragma once` https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/as...
- `absl`: `#ifndef` https://github.com/abseil/abseil-cpp/blob/master/absl/base/a...
- `zpp_bits`: `#ifndef` https://github.com/eyalz800/zpp_bits/blob/main/zpp_bits.h
- `stringzilla` `#ifndef` https://github.com/ashvardanian/StringZilla/blob/main/includ...
But given that I haven't seen any mention of that issue in other comments, I wonder if it really is an issue.
Another idea is to create a Python binding with a release of a package