feat: foreach-style enumerator for top-level groups (#156)#158
Merged
Conversation
Each top-level group on {Msg}DataReader now exposes a property returning a
ref struct enumerator usable with foreach — zero allocation, no closure
capture, ref readonly Current for zero-copy access.
Independent per-group views: each property access creates a fresh enumerator
that computes its start offset by skipping prior groups. This means
out-of-order access, early break, and repeated iteration are all safe and
do not corrupt one another. ReadGroups remains untouched and idempotent.
Gating: emitted only when all top-level groups are simple (no nested groups,
no group-level varData). Complex messages keep ReadGroups only.
- src/SbeCodeGenerator/Generators/Types/MessageDefinition.cs:
AppendGroupEnumerators + HasSimpleTopLevelGroupsForEnumerator gate
- 6 new integration tests covering: in-order iteration, out-of-order access,
repeated iteration, empty groups, early break, BytesConsumed unchanged
- README + CHANGELOG updated, version 1.4.0 -> 1.5.0
Closes #156
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Closes #156.
Summary
Each top-level group on
{Msg}DataReadernow exposes a property returning aref structenumerator usable withforeach— zero allocation, no closure capture,ref readonly Currentfor zero-copy access.Design — independent per-group views
Each property access creates a fresh enumerator that computes its own start offset by chaining static
Skip{Group}helpers across prior groups. This avoids the footgun of a shared cursor:AsksbeforeBids) worksbreakdoes not corrupt later groupsReadGroupscontinues to work unchanged (idempotent)MoveNextandSkiphelpers — malformed buffers returnfalseinstead of throwingGating
Emitted only when all top-level groups are simple (no nested groups, no group-level varData). Complex messages keep
ReadGroupsonly — the foreach API is purely additive.Tests
6 new integration tests in
GroupForeachEnumeratorTests.cs:BytesConsumedis unchanged by foreach (still managed exclusively byReadGroups)Full suite: 187 unit + 144 integration tests green.