Repository navigation
hapi/slots.h: slots, state composed along a chain and addressed by tag - #5
Merged
Merged
Conversation
Slot<Tag,S,Contract> adds one value of type S to the state the components after it built; slot<Tag>(state) reaches it by its tag. One object of static size, no heap, an empty slot adds nothing. The same tag twice (also across nested Chain and APIOf) and an absent tag are compile errors with their own messages. What the state means, how it evolves or travels is not decided here: the Contract parameter is how a user adds members to the state's type. hapi.h includes it. Tests: tests/slots_tests.cpp (tags, each order, the Contract, nested Chain and APIOf), tests/negative/slots_*.cpp, tests/slots/run.sh (same flashed AVR program as a hand-indexed array), tests/single_header/run.sh builds slots_tests both ways. Docs: README "Composing state: slots", docs/REFERENCE.md. CHANGELOG: 0.8.0 heading (the items that came after the v0.7.0 tag, single/hapi.h, Distinct and static_net, move under it with the slots); library.json 0.8.0; single/hapi.h regenerated. From R&D/HAPI/typedState @ 41e4086. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… bytes (measured in CI) The first CI run on MSVC printed the sizes that slots_tests.cpp guards: a state of 6 bytes became 8 with an empty slot; a nested composition is still the same size as the flat one (10 = 10). The README, the header comment, the CHANGELOG and the test comment now say that instead of "adds nothing"; __declspec(empty_bases) was not tried. single/hapi.h regenerated (the header comment). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e class MSVC applies the empty base optimisation to one base only, so an empty slot cost 2 bytes there (CI, first run). The macro is empty on every other compiler and on clang-cl. Whether it brings MSVC back to zero is what this pull request's CI is for; the corrected wording stays until it says so. single/hapi.h regenerated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ecks are unconditional again CI on MSVC with HAPI_EMPTY_BASES (__declspec(empty_bases)): a state with an empty slot is 6 bytes, the same as without; nested and flat are both 10. The two size checks of slots_tests.cpp no longer skip MSVC, so the claim is enforced there by CI; README, CHANGELOG, REFERENCE and the header comment say it without the footnote. single/hapi.h regenerated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Sep 30, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
hapi::Slot<Tag, S, Contract>is a component that adds one value of typeSto the state the components after it built. The state is one object of static size with no heap; a slot is reached by its tag (hapi::slot<Tag>(state)), not by a name or a position; an empty slot adds nothing.ChainorAPIOf) and a tag that is not in the state are compile errors with their own messages.Contract, is how a user adds members to the state's type.each(visitor)callsTag::name()andS::eachonly when it is used.hapi.hincludeshapi/slots.h(lazy instantiation: nothing is paid unless used; the amalgamator needs it reachable).single/hapi.his regenerated.v0.7.0tag (single/hapi.h,Distinct,examples/static_net) move under it together with the slots, so the 0.7.0 section describes what the tag holds again.library.jsonis 0.8.0; the tag itself is not part of this PR.Checked locally
tests/*.cppas CI compiles them (-Wall -Wextra -Wpedantic): all pass on g++ and clang++;tests/slots_tests.cppalso under-Werrorand ASan+UBSan.tests/negative/run.sh: 20/20 on g++ and clang++ (3 new: duplicate tag, duplicate across a nestedAPIOf, missing tag).tests/slots/run.sh: a typed slot access is the same flashed AVR program as a hand-indexed array (264 bytes,avr-g++ -Os, ATmega328p).tests/single_header/run.sh: 36 ok, 0 FAIL (it now also buildsslots_testsfrominclude/and from the single header alone).-fsyntax-only, g++): a chain of 256 slots 1.5 s, against 0.9 s for 256 plain Parts; with the default template depth a chain stops at about 450 Parts, slots or not.Not checked
tests/slots_tests.cppguards the two size checks that depend on empty-base optimisation on_MSC_VER(MSVC lays out several empty bases differently unless__declspec(empty_bases)is used) and prints the sizes instead.Context
This is the slot core of a larger piece of work that keeps everything else out of HAPI (names, a step contract, a schema hash and a wire format live in OneMachine). The evidence, including
static_netconverted on this core alone (same outputs, byte-identical AVR images, measured against the example as it is today), is in the private R&D repository; the example's conversion is a separate, second pull request.🤖 Generated with Claude Code