The descriptor vocabulary for an interval's endpoints — which end (Interval.Bound), whether the endpoint is included (Interval.Boundary), and where a sequence terminates (Interval.Endpoint) — as three small, Foundation-free value types.
Interval is a namespace of descriptors that specify where an interval begins and ends and how its endpoints behave. It holds the labels only — there is no Interval value type here, no comparison, no arithmetic — so the same vocabulary travels unchanged from the package that constructs ranges through every layer that interprets them.
Each descriptor is a two-case enum forming a Z₂ group: every value has a single opposite, reachable by .opposite or the prefix ! operator.
import Interval_Primitives
// Which end of the interval is this value?
let end: Interval.Bound = .upper
print(end.opposite) // lower
print(!end) // lower
// Is the endpoint included in the interval?
let boundary: Interval.Boundary = .closed
print(boundary.isInclusive) // true
print(boundary.toggled) // open
// Where does the sequence terminate?
let position: Interval.Endpoint = .start
print(position.opposite) // endEach descriptor reads in the vocabulary of its caller. Interval.Bound aliases .lower/.upper as .min/.max and .left/.right; Interval.Endpoint aliases .start/.end as .first/.last and .head/.tail. The underlying case is one value, so a .min produced in one module compares equal to a .lower consumed in another.
To carry a payload alongside a descriptor, each type exposes a Value<Payload> typealias — a Pair of the descriptor and the payload:
import Interval_Primitives
import Pair_Primitives
// Tag a number with the bound it represents.
let labelled: Interval.Bound.Value<Int> = Pair(.lower, 0)
print(labelled.first, labelled.second) // lower 0All three descriptors are Sendable, Hashable, CaseIterable, and (outside Embedded) Codable.
dependencies: [
.package(url: "https://github.com/swift-primitives/swift-interval-primitives.git", branch: "main")
].target(
name: "App",
dependencies: [
.product(name: "Interval Primitives", package: "swift-interval-primitives"),
]
)Requires Swift 6.3.1 and macOS 26 / iOS 26 / tvOS 26 / watchOS 26 / visionOS 26 (or the matching Linux / Windows toolchain).
The Interval Primitive target is the dependency-free namespace root; each descriptor lives in its own sub-namespace target so a consumer imports only what it uses. The Interval Primitives umbrella re-exports all of them. The Value<Payload> typealiases depend on the Pair primitive.
| Product | Target | Purpose |
|---|---|---|
Interval Primitive |
Sources/Interval Primitive/ |
The Interval namespace root. Zero external dependencies. |
Interval Bound Primitives |
Sources/Interval Bound Primitives/ |
Interval.Bound — lower/upper endpoint position, with .opposite, aliases (min/max, left/right), and Value<Payload>. |
Interval Boundary Primitives |
Sources/Interval Boundary Primitives/ |
Interval.Boundary — closed/open inclusivity, with isInclusive/isExclusive, toggled, and Value<Payload>. |
Interval Endpoint Primitives |
Sources/Interval Endpoint Primitives/ |
Interval.Endpoint — start/end sequence position, with .opposite, aliases (first/last, head/tail), and Value<Payload>. |
Interval Primitives |
Sources/Interval Primitives/ |
Umbrella re-exporting the namespace and all three descriptor sub-namespaces. |
Interval Primitives Test Support |
Tests/Support/ |
Re-exports the umbrella for test consumers. |
Foundation-free.
| Platform | Status |
|---|---|
| macOS 26 | Full support |
| Linux | Full support |
| Windows | Full support |
| iOS / tvOS / watchOS / visionOS | Supported |
Apache 2.0. See LICENSE.md.