Skip to content

Commit 0f44245

Browse files
committed
Readiness: flip-ready prep for swift-buffer-ring-primitives
- Doc comments on all public declarations; lint conformance (swiftlint --strict + swift format lint --strict both 0). - Family E README; per-package .swift-format / metadata backfill where missing. Floor: clean-room resolve (deps-public verified) + build + test green.
1 parent eb84fb2 commit 0f44245

56 files changed

Lines changed: 392 additions & 191 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/metadata.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# .github/metadata.yaml
2-
description: "The ring buffer discipline over the Buffer namespace — circular, count-tracked storage with wrap-around slots and double-ended front/back access, in growable / bounded / inline / small-buffer flavours; supports ~Copyable elements."
2+
description: "The ring buffer discipline over the Buffer namespace — circular, count-tracked storage with wrap-around slots and double-ended front/back access, in growable and fixed-capacity (bounded) flavours; supports ~Copyable elements."
33
topics:
44
- primitives
55
- buffer

.github/workflows/ci.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
workflow_dispatch:
11+
12+
concurrency:
13+
group: ci-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
# Build + test matrix — see swift-primitives/.github/.github/workflows/swift-ci.yml (layer wrapper, mandates embedded build)
18+
ci:
19+
uses: swift-primitives/.github/.github/workflows/swift-ci.yml@main
20+
secrets: inherit
21+
22+
# DocC umbrella-catalog pipeline per [DOC-019a] — see
23+
# swift-primitives/.github/.github/workflows/swift-docs.yml
24+
docs:
25+
uses: swift-primitives/.github/.github/workflows/swift-docs.yml@main
26+
secrets: inherit

.swift-format

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"version": 1,
3+
"lineLength": 200,
4+
"indentation": {
5+
"spaces": 4
6+
},
7+
"maximumBlankLines": 1,
8+
"respectsExistingLineBreaks": true,
9+
"lineBreakBeforeControlFlowKeywords": false,
10+
"lineBreakBeforeEachArgument": true,
11+
"lineBreakBeforeEachGenericRequirement": true,
12+
"prioritizeKeepingFunctionOutputTogether": true,
13+
"indentConditionalCompilationBlocks": true,
14+
"indentSwitchCaseLabels": false,
15+
"spacesAroundRangeFormationOperators": false,
16+
"fileScopedDeclarationPrivacy": {
17+
"accessLevel": "private"
18+
},
19+
"rules": {
20+
"AllPublicDeclarationsHaveDocumentation": true,
21+
"AlwaysUseLowerCamelCase": false,
22+
"AmbiguousTrailingClosureOverload": true,
23+
"BeginDocumentationCommentWithOneLineSummary": true,
24+
"DoNotUseSemicolons": true,
25+
"DontRepeatTypeInStaticProperties": true,
26+
"FileScopedDeclarationPrivacy": true,
27+
"FullyIndirectEnum": true,
28+
"GroupNumericLiterals": true,
29+
"IdentifiersMustBeASCII": true,
30+
"NeverForceUnwrap": true,
31+
"NeverUseForceTry": true,
32+
"NeverUseImplicitlyUnwrappedOptionals": true,
33+
"NoAccessLevelOnExtensionDeclaration": true,
34+
"NoBlockComments": true,
35+
"NoCasesWithOnlyFallthrough": true,
36+
"NoEmptyTrailingClosureParentheses": true,
37+
"NoLabelsInCasePatterns": true,
38+
"NoLeadingUnderscores": false,
39+
"NoParensAroundConditions": true,
40+
"NoVoidReturnOnFunctionSignature": true,
41+
"OneCasePerLine": true,
42+
"OneVariableDeclarationPerLine": true,
43+
"OnlyOneTrailingClosureArgument": true,
44+
"OrderedImports": true,
45+
"ReturnVoidInsteadOfEmptyTuple": true,
46+
"UseEarlyExits": true,
47+
"UseLetInEveryBoundCaseVariable": true,
48+
"UseShorthandTypeNames": true,
49+
"UseSingleLinePropertyGetter": true,
50+
"UseSynthesizedInitializer": false,
51+
"UseTripleSlashForDocumentationComments": true,
52+
"UseWhereClausesInForLoops": false,
53+
"ValidateDocumentationComments": true
54+
}
55+
}

README.md

Lines changed: 52 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,43 @@
22

33
![Development Status](https://img.shields.io/badge/status-active--development-blue.svg)
44

5-
The **ring buffer discipline** over the `Buffer` namespace: circular, count-tracked storage with
6-
wrap-around physical slots and double-ended front/back access, in four capacity flavours —
7-
growable, bounded, inline, and small-buffer-optimized — all supporting noncopyable (`~Copyable`)
8-
elements.
9-
10-
`Buffer.Ring` is one buffer discipline among siblings; linear, slab, linked, slots, and arena
11-
each live in their own package.
5+
Circular, count-tracked ring buffers over the `Buffer` namespace — double-ended push/pop/peek with O(1) wrap-around at both ends, in growable and fixed-capacity flavours, over copyable and noncopyable elements.
126

137
---
148

159
## Quick Start
1610

11+
A ring buffer keeps its elements in a fixed physical window and wraps the head and tail around it, so neither the front nor the back ever shifts elements — both ends are O(1). Two variants ship here: `Buffer.Ring` (growable) and `Buffer.Ring.Bounded` (fixed-capacity).
12+
1713
```swift
1814
import Buffer_Ring_Primitives
1915

20-
// Growable, heap-backed ring with double-ended push/pop.
21-
var ring = Buffer<Int>.Ring(minimumCapacity: 4)
16+
// These ring buffers pin to heap-backed contiguous storage; alias the spelling once.
17+
typealias Heap<Element> = Storage<Memory.Allocator<Memory.Heap>>.Contiguous<Element>
18+
19+
// A growable, double-ended FIFO. Both ends are O(1): the head and tail wrap around
20+
// a fixed physical window, so neither push nor pop shifts the other elements.
21+
var ring = Buffer<Heap<Int>>.Ring(minimumCapacity: 4)
2222
ring.push.back(1)
2323
ring.push.back(2)
24-
ring.push.front(0)
25-
let head = ring.peek.front // 0
26-
_ = ring.pop.back() // 2
27-
28-
// Small-buffer optimization — inline until it overflows, then spills to the heap.
29-
var small = Buffer<Int>.Ring.Small<4>()
30-
for value in 1...5 { small.push.back(value) } // the 5th push spills to the heap
31-
let spilled = small.isSpilled // true
32-
let front = small.peek.front // 1
24+
ring.push.front(0) // prepend in O(1)
25+
let head = ring.peek.front // 0 — read without removing
26+
let tail = ring.pop.back() // 2 — remove from the back
27+
```
28+
29+
`Buffer.Ring.Bounded` enforces a hard capacity ceiling. A push into a full buffer is *rejected* and handed straight back, so nothing is silently dropped and the buffer never grows:
30+
31+
```swift
32+
import Buffer_Ring_Primitives
33+
34+
var window = Buffer<Heap<Int>>.Ring.Bounded(minimumCapacity: 2)
35+
window.push.back(10)
36+
window.push.back(20)
37+
let rejected = window.push.back(30) // Optional(30): the ceiling is reached
38+
precondition(window.isFull && rejected == 30)
3339
```
3440

35-
A ring stores elements in a fixed physical window and wraps the head/tail around it, so neither
36-
front nor back ever shifts elements — both ends are O(1). `Buffer.Ring.Small` keeps short rings
37-
off the heap entirely and only allocates once they outgrow their inline capacity.
41+
A ring is also constructible declaratively with a result builder (`Buffer<Heap<Int>>.Ring { 1; 2; 3 }`, where declaration order is the FIFO read order), and drains front-to-back through `drain(_:)` / `removeAll()`. When its element is `Copyable` it conforms to `Sequenceable` for single-pass iteration.
3842

3943
---
4044

@@ -50,48 +54,51 @@ dependencies: [
5054
.target(
5155
name: "App",
5256
dependencies: [
53-
// The umbrella — the whole package.
57+
// The umbrella — every variant.
5458
.product(name: "Buffer Ring Primitives", package: "swift-buffer-ring-primitives"),
55-
// …or depend on just the variant you use, e.g.:
56-
// .product(name: "Buffer Ring Small Primitives", package: "swift-buffer-ring-primitives"),
59+
// …or depend on a single variant, e.g. just the bounded type:
60+
// .product(name: "Buffer Ring Bounded Primitive", package: "swift-buffer-ring-primitives"),
5761
]
5862
)
5963
```
6064

61-
The package is pre-1.0 — depend on `branch: "main"` until `0.1.0` is tagged. Requires Swift 6.3
62-
and macOS 26 / iOS 26 / tvOS 26 / watchOS 26 / visionOS 26 (or the matching Linux toolchain).
65+
The package is pre-1.0 — depend on `branch: "main"` until `0.1.0` is tagged.
6366

6467
---
6568

66-
## Variants
69+
## Architecture
70+
71+
Each variant ships as **two modules**: a lean type module (the `~Copyable` value type plus the operations that touch its storage) and an ops/conformances module (the `Copyable`-requiring `Sequence` conformances, kept separate so they never constrain noncopyable use). The `Buffer Ring Primitives` ops module doubles as the umbrella: it re-exports every variant.
6772

68-
| Type | Storage | Reach for it when |
69-
|------|---------|-------------------|
70-
| `Buffer.Ring` | heap, growable | the size isn't known up front |
71-
| `Buffer.Ring.Bounded` | heap, fixed maximum | there is a hard capacity ceiling (push returns the rejected element when full) |
72-
| `Buffer.Ring.Inline<n>` | inline, fixed | the maximum is small and known at compile time |
73-
| `Buffer.Ring.Small<n>` | inline → heap | usually small, occasionally larger (SBO) |
73+
| Product | Target | Purpose |
74+
|---------|--------|---------|
75+
| `Buffer Ring Primitives` | `Sources/Buffer Ring Primitives/` | Umbrella + base ops — re-exports every variant; the `Sequenceable` / `Sequence.Drain` conformances, the scalar iterator, and the `.drain` accessor for `Buffer.Ring`. |
76+
| `Buffer Ring Primitive` | `Sources/Buffer Ring Primitive/` | The lean `Buffer.Ring` type — growable, heap-backed, `~Copyable` — with its push/pop/peek/remove operations, checkpoints, and result builder. |
77+
| `Buffer Ring Bounded Primitive` | `Sources/Buffer Ring Bounded Primitive/` | The lean `Buffer.Ring.Bounded` type — fixed-capacity, heap-backed, `~Copyable` — whose push returns the rejected element when full. |
78+
| `Buffer Ring Bounded Primitives` | `Sources/Buffer Ring Bounded Primitives/` | Bounded ops — the `Sequence.Drain` conformance and `.drain` accessor for `Buffer.Ring.Bounded`. |
79+
| `Buffer Ring Primitives Test Support` | `Tests/Support/` | Re-exports the variant modules for test consumers. |
7480

75-
Every variant is generic over `Element`, including noncopyable element types.
81+
Foundation-free.
7682

7783
---
7884

79-
## Architecture
85+
## Platform Support
8086

81-
Each variant ships as **two modules**: a lean type module (the value type plus the operations
82-
that touch its storage) and a conformances module (the `Sequence` conformances, kept separate so
83-
they never constrain noncopyable use). Importing `Buffer Ring Primitives` brings in the whole
84-
package; importing a single variant module brings in just that variant.
87+
| Platform | Status |
88+
|----------|--------|
89+
| macOS 26 | Full support |
90+
| Linux | Full support |
91+
| Windows | Full support |
92+
| iOS / tvOS / watchOS / visionOS | Supported |
8593

8694
---
8795

88-
## Related Packages
96+
## Community
8997

90-
- [`swift-buffer-primitives`](https://github.com/swift-primitives/swift-buffer-primitives) — the `Buffer` namespace and capacity-growth vocabulary.
91-
- [`swift-storage-primitives`](https://github.com/swift-primitives/swift-storage-primitives) — the heap and inline storage substrate.
92-
- [`swift-cyclic-index-primitives`](https://github.com/swift-primitives/swift-cyclic-index-primitives) — the modular (wrap-around) index arithmetic.
93-
- Sibling disciplines: `swift-buffer-linear-primitives`, `swift-buffer-slab-primitives`, `swift-buffer-linked-primitives`, `swift-buffer-slots-primitives`, `swift-buffer-arena-primitives`.
98+
<!-- BEGIN: discussion -->
99+
<!-- Discussion thread created at publication. -->
100+
<!-- END: discussion -->
94101

95102
## License
96103

97-
Apache License 2.0. See [LICENSE](LICENSE) for details.
104+
Apache 2.0. See [LICENSE.md](LICENSE.md).

Sources/Buffer Ring Bounded Primitive/Buffer.Ring.Bounded Copyable.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
public import Storage_Primitive
1+
import Affine_Primitives_Standard_Library_Integration
2+
public import Index_Primitives
23
public import Memory_Allocator_Primitive
34
public import Memory_Heap_Primitives
4-
public import Storage_Contiguous_Primitives
55
import Ordinal_Primitives_Standard_Library_Integration
6-
import Affine_Primitives_Standard_Library_Integration
7-
public import Index_Primitives
6+
public import Storage_Contiguous_Primitives
7+
public import Storage_Primitive
88

99
// MARK: - Copyable-element features for Buffer.Ring.Bounded
1010
//

Sources/Buffer Ring Bounded Primitive/Buffer.Ring.Bounded+Buffer.Protocol.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ public import Buffer_Protocol_Primitives
2121
/// part of this conformance. The banked `where S: ~Copyable` conformance is
2222
/// preserved.
2323
extension Buffer.Ring.Bounded: Buffer.`Protocol` where S: ~Copyable {
24+
/// The buffered element type, pinned to the substrate's element (`S.Element`).
2425
public typealias Element = S.Element
2526
}

Sources/Buffer Ring Bounded Primitive/Buffer.Ring.Bounded+Builder.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import Ordinal_Primitives_Standard_Library_Integration
21
import Affine_Primitives_Standard_Library_Integration
2+
// Explicit `Buffer.Protocol` import: the @inlinable builder body below uses the
3+
// inherited `isEmpty` default (not relied on transitively); `public` per [MOD-027].
4+
public import Buffer_Protocol_Primitives
5+
import Ordinal_Primitives_Standard_Library_Integration
6+
37
// ===----------------------------------------------------------------------===//
48
//
59
// This source file is part of the swift-primitives open source project
@@ -11,10 +15,6 @@ import Affine_Primitives_Standard_Library_Integration
1115
//
1216
// ===----------------------------------------------------------------------===//
1317

14-
// Explicit `Buffer.Protocol` import: the @inlinable builder body below uses the
15-
// inherited `isEmpty` default (not relied on transitively); `public` per [MOD-027].
16-
public import Buffer_Protocol_Primitives
17-
1818
extension Buffer.Ring.Bounded where S: ~Copyable {
1919
/// Constructs a heap-allocated bounded ring buffer from a result-builder closure.
2020
///

Sources/Buffer Ring Bounded Primitive/Buffer.Ring.Bounded+Checkpoint.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import Ordinal_Primitives_Standard_Library_Integration
21
import Affine_Primitives_Standard_Library_Integration
2+
import Ordinal_Primitives_Standard_Library_Integration
3+
34
// MARK: - Checkpoint for Ring.Bounded
45

56
extension Buffer.Ring.Bounded where S: ~Copyable {

Sources/Buffer Ring Bounded Primitive/Buffer.Ring.Bounded+ConformanceSupport.swift

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
public import Span_Protocol_Primitives
2-
import Ordinal_Primitives_Standard_Library_Integration
31
import Affine_Primitives_Standard_Library_Integration
2+
import Ordinal_Primitives_Standard_Library_Integration
3+
public import Span_Protocol_Primitives
44
public import Storage_Contiguous_Primitives
55

66
// MARK: - Package windows for cold ops-module conformances (refined-C, [MOD-031]/[MOD-036])
@@ -15,13 +15,15 @@ public import Storage_Contiguous_Primitives
1515

1616
extension Buffer.Ring.Bounded where S: ~Copyable {
1717

18-
/// The ring header (head + count + capacity). Package window for the cold
19-
/// `Sequence` conformance.
18+
/// The ring header (head + count + capacity).
19+
///
20+
/// Package window for the cold `Sequence` conformance.
2021
@usableFromInline
2122
package var _header: Buffer.Ring.Header { header }
2223

23-
/// The backing heap storage. Package window for the cold conformances that
24-
/// need a base pointer (`Sequence`).
24+
/// The backing heap storage.
25+
///
26+
/// Package window for the cold conformances that need a base pointer (`Sequence`).
2527
///
2628
/// Yields via a `_read` coroutine (rather than returning by value) because
2729
/// `Storage<Memory.Allocator<Memory.Heap>>.Contiguous<S.Element>` is `~Copyable` and cannot be returned by value
@@ -31,8 +33,9 @@ extension Buffer.Ring.Bounded where S: ~Copyable {
3133
_read { yield storage }
3234
}
3335

34-
/// Consuming drain in FIFO order. Package window for the
35-
/// `Sequence.Drain.Protocol` conformance in the Bounded ops module.
36+
/// Consuming drain in FIFO order.
37+
///
38+
/// Package window for the `Sequence.Drain.Protocol` conformance in the Bounded ops module.
3639
///
3740
/// Seam-generic: each `move(at:)` keeps the ledger COUNT accurate (its shape is
3841
/// prefix-normalized mid-loop, which is only observable on a trap — the body is
@@ -55,8 +58,9 @@ extension Buffer.Ring.Bounded where S: ~Copyable {
5558
extension Buffer.Ring.Bounded where S: Span.`Protocol`, S: ~Copyable {
5659
/// Package window: the storage's count-bounded span, re-anchored through STRUCT containment
5760
/// (`storage` is a stored property here, so its borrow is part of the borrow of `self`; a
58-
/// returning span cannot exit the `_storage` coroutine window's yield scope). NOT public —
59-
/// the count-bounded span under-covers a WRAPPED ring ([MEM-SPAN-004]); the ops modules'
61+
/// returning span cannot exit the `_storage` coroutine window's yield scope).
62+
///
63+
/// NOT public — the count-bounded span under-covers a WRAPPED ring ([MEM-SPAN-004]); the ops modules'
6064
/// iterators consume it segment-wise via the ledger ranges (the shipping contract: the old
6165
/// heap span documented `.two` access as out of contract too).
6266
@inlinable

0 commit comments

Comments
 (0)