Swiftpack.co - Jomy10/swift-soa as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by Jomy10.
Jomy10/swift-soa v2.0.0
Struct of Arrays implementation in pure Swift.
⭐️ 0
🕓 3 days ago
.package(url: "https://github.com/Jomy10/swift-soa.git", from: "v2.0.0")


A struct of arrays implementation in pure Swift.


Add to your package.swift in the dependencies:

.package(url: "https://github.com/jomy10/swift-soa", .branch("master"))

Add to your Package.swift in a target's dependency:

.package(name: "SoA", package: "soa-swift")

New SoA intance

Initialize a Soa instance with an initial capacity of 32 elements.

let soa = SoA(

Changing array capacity

When you want to add more elements than the current capacity of the SoA (soa.capacity), you need to resize it first.

soa.capacity = soa.capacity * 2

Adding elements

When adding elements, you should always make sure you're not adding more elements than the capacity allows.

var soa = SoA(
let idx = 5 // element 5 in array 0 (field 0)
if idx < soa.capacity {
  soa.set(0, at: idx, 69)
} else {
  // resize first

Retrieving elements

soa.get(0, at: idx)

Non-primitive types

If you want to add types like classes to the struct of array, you will have to convert them to a pointer first.

For String types, you can use the designated string functions.

soa.get(1, at: 0) as String?
soa.set(1, at: 0, str: "Hello world")

For pointers:

soa.getBufPtr(1, at: 0)
// set pointer and deallocate previous managed pointer at the specified index
soa.set(1, at: 0, ptr: myPtr)
// set pointer, deallocate previous managed pointer at the specified index,
// and add this pointer to be managed by the `SoA`
soa.set(1, at: 0, managedPtr: myPtr)
// set pointer without trying to deallocate the previous pointer
soa.setUnmanaged(1, at: 0, ptr: myPtr)

Strings will always use the soa.set(Int, at: Int, managedPtr: UnsafeRawBufferPointer).


Using the set method to mutate elements in a loop can be slow, use slice instead.

Primitive types

// Slice field 0
soa.slice(0) { (slice: UnsafeSoASlice<Int>) in
  var slice = slice
  slice[0] = 5


soa.slice(0) { (slice: UnsafeSoASliceBufPtr<MyType>) in
  var slice = slice
  // set pointer and deallocate previous
  slice[0] = otherPointer
  // set pointer and deallocate previous and manage this one
  slice[managedPtr: 0] = otherPointer
  // set pointer without trying to deallocate
  slice[unmanaged: 0] = otherPointer


soa.slice(0) { (slice: UnsafeSoAString) in
  var slice = slice
  slice[0] = "Hello!"


The library is intentionally low-level as it is meant as a "core" library. The user of the library is encouraged to build their own abstraction layer on top of this library.

Running tests

swift test

Running benchmarks



The library is licensed under the GNU LGPL3.0.


Stars: 0
Last commit: 3 days ago
jonrohan Something's broken? Yell at me @ptrpavlik. Praise and feedback (and money) is also welcome.

Release Notes

3 days ago

Rewrite to use byte array to store elements.

Full Changelog: https://github.com/Jomy10/swift-soa/compare/v1.1.0...v2.0.0

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics