[HN Gopher] Show HN: CXXStateTree - A modern C++ library for hie...
___________________________________________________________________
Show HN: CXXStateTree - A modern C++ library for hierarchical state
machines
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! Repo:
https://github.com/ZigRazor/CXXStateTree
Author : zigrazor
Score : 29 points
Date : 2025-07-07 06:06 UTC (3 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| jeffreygoesto wrote:
| Nice and compact. I only wound have two nitpicks:
|
| 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.
| zigrazor wrote:
| yes, it means "zero allocations after state tree building".
| Thank you for the suggestions, I think we could separate target
| with compilation switch. If you want you can open an issue on
| the repo. Thank you so much
| happyweasel wrote:
| vcpkg it
| zigrazor wrote:
| You can open an Issue on that on the repo
| (https://github.com/ZigRazor/CXXStateTree/issues) so we can
| track these changes.
|
| Another idea is to create a Python binding with a release of a
| package
| dgan wrote:
| i am by no means a C++ expert, but isn't "pragma once" frowned
| upon?
| kookamamie wrote:
| No, it is the way. Edit: no one has time for inventing unique
| names for include guards.
| hdhdjd wrote:
| Does anyone write those by hand anyway in any kind of project
| the size where it would matter?
|
| #pragma once is broken by design
| bogwog wrote:
| I don't understand what you're saying here. #pragma once
| does the job that include guards used to do, but with less
| work, and in a less error prone way. How is it broken, and
| how is the size of a project relevant?
| motorest wrote:
| > I don't understand what you're saying here. #pragma
| once does the job that include guards used to do, (...)
|
| They don't. They are not C++ and at most they are
| compiler-specific.
|
| It's fine if you opt to not write C++ and instead target
| specific compilers instead. Just don't pretend it's not
| frowned upon or kosher.
| bogwog wrote:
| TIL about the existence of a passionate #pragma once
| hating subculture.
|
| Since you seem to be more knowledgeble about this, I'm
| curious to know which C++ compilers lack support? I know
| that at least the 3 big ones do (GCC, Clang, and MSVC)
| and they have for a very long time.
| quietbritishjim wrote:
| > Does anyone write those by hand anyway in any kind of
| project the size where it would matter?
|
| I think you're suggesting that you don't need to make up
| the names for include guards because all tools / IDEs for
| C++ write them for you automatically anyway. But that isn't
| my experience. Many IDEs don't write include guards for you
| automatically ... because everybody uses #pragma once
| already.
|
| > #pragma once is broken by design
|
| I think you're referring to the historical problem with
| #pragma once, which is that it can be hard for the compiler
| to identify what is _really_ the same file (and therefore
| shouldn 't be included a second time). If you hard link to
| the same file, or soft link to it, is it the same? What if
| the same file is mapped to two different mount points? What
| if genuinely different files have the same contents (e.g.,
| because the same library is included from two different
| installation paths)? In practice, soft/hard links to the
| same file are easily detectable, and anything more obscure
| indicates such a weird problem with your setup that you
| surely have bigger issues. #pragma once is _fine_.
|
| (Historically, it also had the benefit that compilers would
| know not to even re-read the header, whereas with
| traditional include guards they would need to re-include
| the file (e.g. in case the whole file is not wrapped in the
| #ifdef, or in case something else has undefined it since)
| only to then discard the contents. I've even seen coding
| guidelines requiring _external_ include guards wrapped
| around every use of headers with #include <...>. Yuck! But
| modern compilers can work out when include guards are meant
| to mean that so today that difference probably no longer
| exists.)
| motorest wrote:
| > No, it is the way.
|
| 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.
| quietbritishjim wrote:
| What major compiler does not support it?
| motorest wrote:
| > What major compiler does not support it?
|
| The whole point is that it's not supported and it's not
| standard, thus using #pragma once needlessly introduced
| the risk of having the code break.
|
| You should ask yourself what are you doing and why are
| you using non-standard constructs that may or may not
| work, specially when it's rather obvious and trivial to
| just use include guards. Using #pragma once isn't even
| qualify as being clever to gain anything.
| phkahler wrote:
| Maybe you should ask why you're using a non-standard
| compiler if it's not supported.
|
| Not being part of the official standard doesn't
| necessarily mean it's not well supported.
| AndriyKunitsyn wrote:
| The whole point of C/C++ is knowing your environment.
| It's not Java, it's not TypeScript. It's one level above
| assembly, and if you change the compiler and things
| break, then it's your fault.
|
| If the standards still don't have a proper replacement
| for include guards, then too bad for the standards. The
| C++ standard wasn't aware of multithreading before C++11,
| this didn't stop people from writing multithreaded
| programs.
|
| As to why - #pragma once is just cleaner to look at.
| spacechild1 wrote:
| Yes, it is non-standard, but I don't know any compiler that
| does not support it.
| baymotion wrote:
| Related idea for those using python:
| https://github.com/baymotion/smax.
___________________________________________________________________
(page generated 2025-07-10 23:01 UTC)